File size: 4,903 Bytes
052b859
9dda31e
 
36599ed
 
 
 
052b859
9dda31e
eece69a
052b859
eece69a
 
9dda31e
eece69a
052b859
 
142a9b8
052b859
 
 
 
 
eece69a
7f92e26
 
 
 
2970d8e
 
7f92e26
 
 
 
 
052b859
 
36599ed
eece69a
36599ed
 
 
052b859
 
9dda31e
 
 
 
 
 
440d105
9dda31e
36599ed
eece69a
 
 
 
7f92e26
36599ed
052b859
c75b701
36599ed
052b859
 
eece69a
052b859
 
7f92e26
052b859
 
 
eece69a
052b859
 
36599ed
22ee258
c75b701
22ee258
 
 
c75b701
22ee258
c75b701
22ee258
 
36599ed
 
 
 
 
 
 
 
 
 
052b859
 
 
 
 
 
 
 
36599ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
052b859
 
 
 
 
 
 
 
eece69a
 
 
052b859
36599ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import json
import random
import time

import streamlit as st

from categories.accuracy import *
from categories.fluency import *
from categories.style import *
from modules.nav import Navbar

Navbar()


# Load translations from a JSON file to be used by the bot
def load_translations():
    try:
        with open("./data/translations.json", "r") as f:
            return json.loads(f.read())
    except Exception as e:
        print(e)
        return None


def score(score):
    if score > 90:
        return "excellent!"
    elif score > 70:
        return "good."
    elif score > 50:
        return "fair."
    else:
        return "poor."


if "translations" not in st.session_state:
    st.session_state.translations = load_translations()


def response_generator(prompt):
    source = st.session_state.german
    acc = accuracy(source, prompt)
    ppl = pseudo_perplexity(prompt)
    gre = grammar_errors(prompt)
    frm = formality(source, prompt)

    total_score = (
        0.5 * acc["score"]
        + 0.2 * gre["score"]
        + 0.3 * ppl["score"]
        + 0.005 * frm["normalized"]
    )

    if "scores" not in st.session_state:
        st.session_state.scores = []
    st.session_state.scores.append(total_score)

    response = f"Your translation quality was {score(total_score)}\n\n"

    acc_s = acc["score"]
    response += f"\nYour accuracy score is {score(acc_s)}\n"

    for error in acc["errors"]:
        response += f" - {error['message']}\n"

    gre_s = gre["score"]
    ppl_s = ppl["score"]
    response += f"\nYour fluency score is {score(0.4 * gre_s + 0.6 * ppl_s)}\n"

    for error in gre["errors"]:
        response += f" - {error['message']}\n"

    for error in ppl["errors"]:
        response += f" - {error['message']}\n"

    frm_s = frm["normalized"]
    response += f"\nYour formality score is {score(frm_s)}\n"

    if frm["src_label"] != frm["trg_label"]:
        response += (
            f"\n - Tone mismatch: "
            f"your translation is β€œ{frm['trg_label']}”\n"
            f"but likely should be β€œ{frm['src_label']}”. "
        )

    lines = response.split("\n")
    for line in lines:
        for word in line.split():
            yield word + " "
            time.sleep(0.05)
        # After each line, yield a newline character or trigger a line break in Markdown
        yield "\n"


def translation_generator():
    # Check if translations are available and not empty
    if st.session_state.translations:
        # Randomly select a translation from the list
        st.session_state.german = random.choice(st.session_state.translations)["german"]
    else:
        st.error("No translations available.")
        return

    message = (
        f"Please translate the following sentence into English:"
        f" {st.session_state.german}"
    )

    lines = message.split("\n")
    for line in lines:
        for word in line.split():
            yield word + " "
            time.sleep(0.05)
        # After each line, yield a newline character or trigger a line break in Markdown
        yield "\n"


# Initialize chat history
if "messages" not in st.session_state:
    st.session_state.messages = [
        {
            "role": "assistant",
            "content": (
                "Hello! I am a translation bot. Please translate the following"
                " sentence into English: 'Das ist ein Test.'"
            ),
        }
    ]
    st.session_state.german = "Das ist ein Test."

if "translations" not in st.session_state:
    try:
        with open("translations.json", "r") as f:
            st.session_state.translations = json.loads(f.read())
            print(st.session_state.translations)
    except (FileNotFoundError, json.JSONDecodeError):
        st.session_state.translations = None
        # Create an empty translations dictionary if none exists
        st.error(
            "No previous translations found. Starting with an empty translation history."
        )

# Display chat messages from history on app rerun
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# Accept user input
if prompt := st.chat_input("What is up?"):
    # Add user message to chat history
    st.session_state.messages.append({"role": "user", "content": prompt})
    # Display user message in chat message container
    with st.chat_message("user"):
        st.markdown(prompt)

    # Display assistant response in chat message container
    with st.chat_message("assistant"):
        response = st.write_stream(response_generator(prompt))

    st.session_state.messages.append({"role": "assistant", "content": response})

    with st.chat_message("assistant"):
        message = st.write_stream(translation_generator())

    st.session_state.messages.append({"role": "assistant", "content": message})
    # Add assistant response to chat history