Spaces:
Sleeping
Sleeping
Upload 6 files
Browse files- app.py +55 -0
- constants.py +25 -0
- flashcard.py +242 -0
- import_export_page.py +48 -0
- requirements.txt +4 -0
- show_generator_page.py +125 -0
app.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" Flashcards generator using LLM as a backend """
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
# from dotenv import find_dotenv, load_dotenv
|
5 |
+
|
6 |
+
from flashcard import Flashcards
|
7 |
+
# Importing page modules
|
8 |
+
from import_export_page import show_import_export_page
|
9 |
+
from show_generator_page import show_generator_page
|
10 |
+
|
11 |
+
|
12 |
+
def main():
|
13 |
+
"""
|
14 |
+
Main function to run the Streamlit app for flashcard generation and management.
|
15 |
+
|
16 |
+
This function initializes the app, setting up the page configuration and session state.
|
17 |
+
It provides navigation between the flashcard generator and import/export pages.
|
18 |
+
"""
|
19 |
+
|
20 |
+
# Load environment variables from .env file
|
21 |
+
# load_dotenv(find_dotenv())
|
22 |
+
|
23 |
+
# Set Streamlit page configuration
|
24 |
+
st.set_page_config(page_title="FG", layout="centered", initial_sidebar_state="auto")
|
25 |
+
|
26 |
+
# Initialize flashcards in session state if not already present
|
27 |
+
if "flashcards" not in st.session_state:
|
28 |
+
st.session_state.flashcards = Flashcards([])
|
29 |
+
|
30 |
+
# Initialize expand_all toggle state in session state
|
31 |
+
if "expand_all" not in st.session_state:
|
32 |
+
st.session_state.expand_all = False
|
33 |
+
|
34 |
+
# Define navigation options
|
35 |
+
generator_choice = "🤖 Generator"
|
36 |
+
import_export_choice = "📂 Import/Export"
|
37 |
+
|
38 |
+
# Sidebar for navigation
|
39 |
+
with st.sidebar:
|
40 |
+
# Display application logo
|
41 |
+
st.image(
|
42 |
+
"https://github.com/mikkac/flashcards_generator/blob/main/resources/logo.png?raw=true"
|
43 |
+
)
|
44 |
+
# Radio buttons for page selection
|
45 |
+
choice = st.radio("Select Page", (generator_choice, import_export_choice))
|
46 |
+
|
47 |
+
# Conditional rendering of pages based on user choice
|
48 |
+
if choice == generator_choice:
|
49 |
+
show_generator_page()
|
50 |
+
elif choice == import_export_choice:
|
51 |
+
show_import_export_page()
|
52 |
+
|
53 |
+
|
54 |
+
if __name__ == "__main__":
|
55 |
+
main()
|
constants.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" File with constants """
|
2 |
+
|
3 |
+
languages = [
|
4 |
+
"English",
|
5 |
+
"Spanish",
|
6 |
+
"Polish",
|
7 |
+
"Chinese",
|
8 |
+
"Hindi",
|
9 |
+
"Arabic",
|
10 |
+
"Portuguese",
|
11 |
+
"Bengali",
|
12 |
+
"Russian",
|
13 |
+
"Japanese",
|
14 |
+
]
|
15 |
+
|
16 |
+
language_to_flag = {
|
17 |
+
"English": "🇬🇧", # Flag of the United Kingdom
|
18 |
+
"Spanish": "🇪🇸", # Flag of Spain
|
19 |
+
"Polish": "🇵🇱", # Flag of Poland
|
20 |
+
"Chinese": "🇨🇳", # Flag of China
|
21 |
+
"Hindi": "🇮🇳", # Flag of India
|
22 |
+
"Arabic": "🇸🇦", # Flag of Saudi Arabia (Arabic is widely spoken in many countries)
|
23 |
+
"Portuguese": "🇵🇹", # Flag of Portugal
|
24 |
+
"Japanese": "🇯,,🇵" # Flag of Japan
|
25 |
+
}
|
flashcard.py
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" File that contains flashcards' backend """
|
2 |
+
import json
|
3 |
+
import os
|
4 |
+
from dataclasses import asdict, dataclass
|
5 |
+
|
6 |
+
# from dotenv import find_dotenv, load_dotenv
|
7 |
+
from langchain.chat_models import ChatOpenAI
|
8 |
+
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
|
9 |
+
from langchain.prompts import ChatPromptTemplate
|
10 |
+
|
11 |
+
|
12 |
+
@dataclass
|
13 |
+
class Flashcard:
|
14 |
+
"""
|
15 |
+
Represents a flashcard containing language translation information.
|
16 |
+
|
17 |
+
Attributes:
|
18 |
+
input_expression (str): The expression in the input language.
|
19 |
+
input_language (str): The language of the input expression.
|
20 |
+
output_expression (str): The translated expression in the output language.
|
21 |
+
output_language (str): The language of the output expression.
|
22 |
+
example_usage (str): An example usage of the input expression in a sentence.
|
23 |
+
"""
|
24 |
+
|
25 |
+
input_expression: str
|
26 |
+
input_language: str
|
27 |
+
output_expression: str
|
28 |
+
output_language: str
|
29 |
+
example_usage: str
|
30 |
+
|
31 |
+
@classmethod
|
32 |
+
def from_dict(cls, data: dict) -> "Flashcard":
|
33 |
+
"""
|
34 |
+
Creates a Flashcard instance from a dictionary of attributes.
|
35 |
+
|
36 |
+
Args:
|
37 |
+
data (dict): A dictionary containing flashcard attributes.
|
38 |
+
|
39 |
+
Returns:
|
40 |
+
Flashcard: An instance of Flashcard.
|
41 |
+
"""
|
42 |
+
return cls(
|
43 |
+
input_expression=data.get("input_expression", None),
|
44 |
+
input_language=data.get("input_language", None),
|
45 |
+
output_expression=data.get("output_expression", None),
|
46 |
+
output_language=data.get("output_language", None),
|
47 |
+
example_usage=data.get("example_usage", None),
|
48 |
+
)
|
49 |
+
|
50 |
+
|
51 |
+
@dataclass
|
52 |
+
class Flashcards:
|
53 |
+
"""
|
54 |
+
Represents a collection of Flashcard instances.
|
55 |
+
|
56 |
+
Attributes:
|
57 |
+
data (list[Flashcard]): A list of Flashcard instances.
|
58 |
+
"""
|
59 |
+
|
60 |
+
data: list[Flashcard]
|
61 |
+
|
62 |
+
def as_json(self) -> dict:
|
63 |
+
"""
|
64 |
+
Converts the collection of Flashcard instances to a JSON format.
|
65 |
+
|
66 |
+
Returns:
|
67 |
+
dict: A dictionary representing the flashcards in JSON format.
|
68 |
+
"""
|
69 |
+
return {"flashcards": [asdict(card) for card in self.data]}
|
70 |
+
|
71 |
+
@classmethod
|
72 |
+
def import_from_json(cls, data: dict) -> "Flashcards":
|
73 |
+
"""
|
74 |
+
Creates a Flashcards instance from a JSON file.
|
75 |
+
|
76 |
+
Args:
|
77 |
+
data (file): A JSON file containing flashcard data.
|
78 |
+
|
79 |
+
Returns:
|
80 |
+
Flashcards: An instance of Flashcards containing the imported data.
|
81 |
+
"""
|
82 |
+
data = json.load(data)
|
83 |
+
flashcard_objects = [Flashcard(**card) for card in data["flashcards"]]
|
84 |
+
return cls(data=flashcard_objects)
|
85 |
+
|
86 |
+
def __len__(self) -> int:
|
87 |
+
"""
|
88 |
+
Returns the number of Flashcard instances in the collection.
|
89 |
+
|
90 |
+
Returns:
|
91 |
+
int: The number of Flashcard instances.
|
92 |
+
"""
|
93 |
+
return len(self.data)
|
94 |
+
|
95 |
+
|
96 |
+
class FlashcardGeneratorOpenAI: # pylint: disable=R0903
|
97 |
+
"""
|
98 |
+
A class to generate language learning flashcards using OpenAI's language model.
|
99 |
+
|
100 |
+
Attributes:
|
101 |
+
chat (ChatOpenAI): An instance of ChatOpenAI for generating flashcards.
|
102 |
+
response_schemas (list): A list of ResponseSchema objects for structuring the response.
|
103 |
+
output_parser (StructuredOutputParser): Parser to structure the output
|
104 |
+
from the language model.
|
105 |
+
flashcard_generator_template (str): A template for generating flashcard data.
|
106 |
+
prompt (ChatPromptTemplate): A prompt template for the language model.
|
107 |
+
"""
|
108 |
+
|
109 |
+
def __init__(self, api_key: str, llm_model: str = "gpt-3.5-turbo") -> None:
|
110 |
+
"""
|
111 |
+
Initializes the FlashcardGeneratorOpenAI class with
|
112 |
+
the specified API key and language model.
|
113 |
+
|
114 |
+
Args:
|
115 |
+
api_key (str): The API key for OpenAI.
|
116 |
+
llm_model (str): The name of the language model to use.
|
117 |
+
"""
|
118 |
+
self.chat = ChatOpenAI(temperature=0.0, model=llm_model, api_key=api_key)
|
119 |
+
|
120 |
+
input_expression_schema = ResponseSchema(
|
121 |
+
name="input_expression",
|
122 |
+
type="str",
|
123 |
+
description="Original expression entered by the user, refined"
|
124 |
+
" to create translated_expression.",
|
125 |
+
)
|
126 |
+
input_language_schema = ResponseSchema(
|
127 |
+
name="input_language",
|
128 |
+
type="str",
|
129 |
+
description="Language of the input expression.",
|
130 |
+
)
|
131 |
+
output_expression_schema = ResponseSchema(
|
132 |
+
name="output_expression",
|
133 |
+
type="str",
|
134 |
+
description="Translation of refined expression entered by the user.",
|
135 |
+
)
|
136 |
+
output_language_schema = ResponseSchema(
|
137 |
+
name="output_language",
|
138 |
+
type="str",
|
139 |
+
description="Language of the output expression.",
|
140 |
+
)
|
141 |
+
example_usage_schema = ResponseSchema(
|
142 |
+
name="example_usage",
|
143 |
+
type="str",
|
144 |
+
description="Example usage of input expression, used to give the user some "
|
145 |
+
"example context where it could be used. Limited to one sentence.",
|
146 |
+
)
|
147 |
+
|
148 |
+
response_schemas = [
|
149 |
+
input_expression_schema,
|
150 |
+
input_language_schema,
|
151 |
+
output_expression_schema,
|
152 |
+
output_language_schema,
|
153 |
+
example_usage_schema,
|
154 |
+
]
|
155 |
+
|
156 |
+
self.output_parser = StructuredOutputParser.from_response_schemas(
|
157 |
+
response_schemas
|
158 |
+
)
|
159 |
+
self.format_instructions = self.output_parser.get_format_instructions()
|
160 |
+
|
161 |
+
self.flashcard_generator_template = """\
|
162 |
+
For the following expression, extract the following information:
|
163 |
+
|
164 |
+
input_expression: Original expression entered by the user, but refined to create translated_expression (for flashcard for language learning). If the expression is too long (more than 10 words), it should be shortened while keeping the sense.
|
165 |
+
|
166 |
+
input_language: Language of the input expression
|
167 |
+
|
168 |
+
output_expression: Refined input expression translated to {output_language} language. Provide 2 alternatives, separated with 'slash' sign (and space before & after the sign).
|
169 |
+
|
170 |
+
example_usage: Example usage of input expression, used to give the user some example context where it could be used. Limited to one sentence.
|
171 |
+
|
172 |
+
input_expression: {input_expression}
|
173 |
+
input_language: {input_language}
|
174 |
+
|
175 |
+
{format_instructions}
|
176 |
+
"""
|
177 |
+
|
178 |
+
self.prompt = ChatPromptTemplate.from_template(
|
179 |
+
template=self.flashcard_generator_template
|
180 |
+
)
|
181 |
+
|
182 |
+
def generate_flashcard(
|
183 |
+
self, input_exp: str, input_lang: str, output_lang: str
|
184 |
+
) -> Flashcard:
|
185 |
+
"""
|
186 |
+
Generates a flashcard by translating an input expression from one language to another.
|
187 |
+
|
188 |
+
This method takes an expression in a specified input language, translates it into
|
189 |
+
a specified output language, and then creates a flashcard containing both the original
|
190 |
+
and translated expressions. It uses the ChatOpenAI model to generate the translation
|
191 |
+
and example usage.
|
192 |
+
|
193 |
+
Args:
|
194 |
+
input_expression (str): The expression to be translated.
|
195 |
+
input_language (str): The language of the input expression.
|
196 |
+
output_language (str): The language into which the input expression is to be translated.
|
197 |
+
|
198 |
+
Returns:
|
199 |
+
Flashcard: An instance of the Flashcard class containing the original expression,
|
200 |
+
its translation, and an example usage in the output language.
|
201 |
+
"""
|
202 |
+
messages = self.prompt.format_messages(
|
203 |
+
input_expression=input_exp,
|
204 |
+
input_language=input_lang,
|
205 |
+
output_language=output_lang,
|
206 |
+
format_instructions=self.format_instructions,
|
207 |
+
)
|
208 |
+
response = self.chat(messages)
|
209 |
+
flashcard_dict = self.output_parser.parse(response.content)
|
210 |
+
return Flashcard.from_dict(flashcard_dict)
|
211 |
+
|
212 |
+
|
213 |
+
def main():
|
214 |
+
"""
|
215 |
+
For debugging purposes only
|
216 |
+
"""
|
217 |
+
# _ = load_dotenv(find_dotenv()) # Read local .env file
|
218 |
+
|
219 |
+
generator = FlashcardGeneratorOpenAI(api_key=os.environ["OPENAI_API_KEY"])
|
220 |
+
|
221 |
+
input_expressions = [
|
222 |
+
"cruel",
|
223 |
+
"let someone off the hook",
|
224 |
+
"it absorbed me",
|
225 |
+
"get my thoughts in order",
|
226 |
+
"crude",
|
227 |
+
"pore over",
|
228 |
+
]
|
229 |
+
input_language = "English"
|
230 |
+
output_language = "Polish"
|
231 |
+
|
232 |
+
flashcards = Flashcards([])
|
233 |
+
|
234 |
+
for input_expression in input_expressions:
|
235 |
+
flashcard = generator.generate_flashcard(
|
236 |
+
input_expression, input_language, output_language
|
237 |
+
)
|
238 |
+
print(flashcard)
|
239 |
+
flashcards.data.append(flashcard)
|
240 |
+
|
241 |
+
if __name__ == "__main__":
|
242 |
+
main()
|
import_export_page.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" Import/export page definition """
|
2 |
+
import json
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
|
6 |
+
from flashcard import Flashcards
|
7 |
+
|
8 |
+
|
9 |
+
def show_import_export_page():
|
10 |
+
"""
|
11 |
+
Defines a Streamlit page for importing and exporting flashcards.
|
12 |
+
|
13 |
+
This function creates an interface where users can upload a JSON file
|
14 |
+
to import flashcards, and download a JSON file containing the current
|
15 |
+
flashcards stored in the session state. It handles file upload, file validation,
|
16 |
+
and displays success or error messages accordingly.
|
17 |
+
"""
|
18 |
+
|
19 |
+
# Displaying a header for the import section
|
20 |
+
st.header("Import file with flashcards")
|
21 |
+
|
22 |
+
# File uploader widget allowing the user to upload a JSON file
|
23 |
+
flashcards_file = st.file_uploader("Select a file", type="json")
|
24 |
+
|
25 |
+
# Handling the uploaded file
|
26 |
+
if flashcards_file is not None:
|
27 |
+
try:
|
28 |
+
# Attempt to import flashcards from the uploaded file
|
29 |
+
st.session_state.flashcards = Flashcards.import_from_json(flashcards_file)
|
30 |
+
print(st.session_state.flashcards.as_json()) # Debug print statement
|
31 |
+
st.success(f"Imported {len(st.session_state.flashcards)} flashcards!")
|
32 |
+
except json.JSONDecodeError:
|
33 |
+
# Handling invalid JSON files
|
34 |
+
st.error("Invalid JSON file. Please upload a valid JSON file.")
|
35 |
+
|
36 |
+
# Divider to separate import and export sections
|
37 |
+
st.divider()
|
38 |
+
|
39 |
+
# Displaying a header for the export section
|
40 |
+
st.header("Export generated flashcards")
|
41 |
+
|
42 |
+
# Download button to export the flashcards as a JSON file
|
43 |
+
st.download_button(
|
44 |
+
"Download flashcards",
|
45 |
+
data=json.dumps(st.session_state.flashcards.as_json(), indent=4),
|
46 |
+
file_name="flashcards_export.json",
|
47 |
+
mime="application/json",
|
48 |
+
)
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
langchain
|
3 |
+
json
|
4 |
+
dataclasses
|
show_generator_page.py
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" Flashcards generator page definition """
|
2 |
+
import os
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
|
6 |
+
from constants import language_to_flag, languages
|
7 |
+
from flashcard import Flashcard, FlashcardGeneratorOpenAI
|
8 |
+
|
9 |
+
|
10 |
+
def create_flashcard(
|
11 |
+
expression: str, input_language: str, output_language: str
|
12 |
+
) -> Flashcard:
|
13 |
+
"""
|
14 |
+
Creates a Flashcard instance with given expression and languages.
|
15 |
+
|
16 |
+
Args:
|
17 |
+
expression (str): The expression to be included in the flashcard.
|
18 |
+
input_language (str): The language of the input expression.
|
19 |
+
output_language (str): The target language for translation.
|
20 |
+
|
21 |
+
Returns:
|
22 |
+
Flashcard: A new Flashcard instance.
|
23 |
+
"""
|
24 |
+
return Flashcard(
|
25 |
+
input_expression=expression,
|
26 |
+
input_language=input_language,
|
27 |
+
output_expression=None,
|
28 |
+
output_language=output_language,
|
29 |
+
example_usage=None,
|
30 |
+
)
|
31 |
+
|
32 |
+
|
33 |
+
def create_toggle(col, original: str, translation: str, example: str):
|
34 |
+
"""
|
35 |
+
Creates a toggle (expandable section) in the Streamlit app.
|
36 |
+
|
37 |
+
Args:
|
38 |
+
col: The Streamlit column where the toggle will be placed.
|
39 |
+
original (str): The original expression to be displayed.
|
40 |
+
translation (str): The translated expression.
|
41 |
+
example (str): An example usage of the expression.
|
42 |
+
id (str): A unique identifier for the toggle.
|
43 |
+
"""
|
44 |
+
with col:
|
45 |
+
with st.expander(original, expanded=st.session_state.expand_all):
|
46 |
+
st.write(f"**{translation}**\n\n{example}")
|
47 |
+
|
48 |
+
|
49 |
+
def show_generator(generator: FlashcardGeneratorOpenAI):
|
50 |
+
"""
|
51 |
+
Displays the flashcard generator interface in the Streamlit app.
|
52 |
+
|
53 |
+
Args:
|
54 |
+
generator (FlashcardGeneratorOpenAI): The flashcard generator object.
|
55 |
+
"""
|
56 |
+
col1, col2 = st.columns(2)
|
57 |
+
with col1:
|
58 |
+
input_language = st.selectbox(
|
59 |
+
"Select an input language:", languages, index=languages.index("English")
|
60 |
+
)
|
61 |
+
with col2:
|
62 |
+
output_language = st.selectbox(
|
63 |
+
"Select an output language:", languages, index=languages.index("Polish")
|
64 |
+
)
|
65 |
+
|
66 |
+
if "input_language" not in st.session_state:
|
67 |
+
st.session_state.input_language = input_language
|
68 |
+
st.session_state.input_language = input_language
|
69 |
+
|
70 |
+
if "output_language" not in st.session_state:
|
71 |
+
st.session_state.output_language = output_language
|
72 |
+
st.session_state.output_language = output_language
|
73 |
+
|
74 |
+
expression = st.text_input(
|
75 |
+
"Expression",
|
76 |
+
placeholder="Enter an expression and press Enter to generate a flashcard",
|
77 |
+
)
|
78 |
+
|
79 |
+
if expression and not any(
|
80 |
+
flashcard.input_expression == expression
|
81 |
+
for flashcard in st.session_state.flashcards.data
|
82 |
+
):
|
83 |
+
new_flashcard = generator.generate_flashcard(
|
84 |
+
expression, input_language, output_language
|
85 |
+
)
|
86 |
+
st.session_state.flashcards.data.append(new_flashcard)
|
87 |
+
|
88 |
+
|
89 |
+
def show_expand_button():
|
90 |
+
"""
|
91 |
+
Displays a button to expand or collapse all flashcards in the Streamlit app.
|
92 |
+
"""
|
93 |
+
if st.button("Expand/Collapse All"):
|
94 |
+
st.session_state.expand_all = not st.session_state.expand_all
|
95 |
+
|
96 |
+
|
97 |
+
def show_flashcards():
|
98 |
+
"""
|
99 |
+
Displays the generated flashcards in the Streamlit app.
|
100 |
+
"""
|
101 |
+
if len(st.session_state.flashcards) == 0:
|
102 |
+
st.info("Generate a flashcard or import a file with previously generated ones")
|
103 |
+
else:
|
104 |
+
col1, col2 = st.columns(2)
|
105 |
+
for idx, flashcard in enumerate(st.session_state.flashcards.data):
|
106 |
+
create_toggle(
|
107 |
+
col1 if idx % 2 == 0 else col2,
|
108 |
+
f"{language_to_flag[flashcard.input_language]} {flashcard.input_expression}",
|
109 |
+
f"{language_to_flag[flashcard.output_language]} {flashcard.output_expression}",
|
110 |
+
f"{flashcard.example_usage}",
|
111 |
+
)
|
112 |
+
|
113 |
+
|
114 |
+
def show_generator_page():
|
115 |
+
"""
|
116 |
+
Sets up the main page of the Streamlit app for the flashcard generator.
|
117 |
+
"""
|
118 |
+
generator = FlashcardGeneratorOpenAI(api_key=os.environ["OPENAI_API_KEY"])
|
119 |
+
|
120 |
+
st.title("Flashcards generator")
|
121 |
+
show_generator(generator)
|
122 |
+
|
123 |
+
st.divider()
|
124 |
+
show_expand_button()
|
125 |
+
show_flashcards()
|