Fractions are a fundamental part of mathematics education and have practical applications in fields such as engineering, finance, and data analysis. However, automating fraction arithmetic is a non-trivial task, especially when the input is expressed as human-readable text (e.g., “1/2 + 1/3”).

Traditionally, such problems are solved using rule-based algorithms that parse and compute exact answers. But what if we could teach a machine learning (ML) model to understand and solve these problems by learning patterns from examples? This approach not only offers opportunities for innovation but also opens the door to interactive educational tools, AI tutors, and intelligent calculators.

In this project, we’ll walk through building a fraction problem solver using machine learning on an Ubuntu 24.04 cloud GPU server.

Prerequisites

  • An Ubuntu 24.04 server with an NVIDIA GPU.
  • A non-root user or a user with sudo privileges.
  • NVIDIA drivers are installed on your server.

Step 1: Set up Python Environment

Before we start generating datasets or training models, we need a clean and isolated Python environment with the required libraries.

1. Install core dependencies.

apt install -y python3 python3-pip python3-venv

2. Create a virtual environment.

python3 -m venv ml-fraction-env

3. Activate the environment to make sure all Python libraries are installed locally within it.

source ml-fraction-env/bin/activate

4. Upgrade pip and install all the libraries we’ll need for this project, including NumPy, pandas, TensorFlow, and Flask.

pip install --upgrade pip
pip install numpy pandas tensorflow flask

Step 2: Generate Dataset

To train a machine learning model that can “understand” and solve fraction problems, we need a large dataset containing fraction expressions and their correct solutions. Instead of manually collecting data, we can generate synthetic data programmatically.

1. Write a Python script (generate_dataset.py) that automatically generates random fraction problems using basic arithmetic operators (+, −, ×, ÷) and computes their exact solutions.

nano generate_dataset.py

Add the following code.

import random
from fractions import Fraction
import pandas as pd

def random_fraction():
    numerator = random.randint(1, 10)
    denominator = random.randint(1, 10)
    return Fraction(numerator, denominator)

def generate_problem():
    ops = ['+', '-', '*', '/']
    a = random_fraction()
    b = random_fraction()
    op = random.choice(ops)
    problem = f"{a} {op} {b}"

    try:
        if op == '+':
            solution = a + b
        elif op == '-':
            solution = a - b
        elif op == '*':
            solution = a * b
        elif op == '/':
            solution = a / b if b != 0 else 'undefined'
    except:
        solution = 'undefined'

    return problem, str(solution)

# Generate 100,000 records
data = [generate_problem() for _ in range(100000)]
df = pd.DataFrame(data, columns=['problem', 'solution'])
df.to_csv('fraction_dataset.csv', index=False)

print("✅ Dataset saved to fraction_dataset.csv")

2. Run the script to generate and save the dataset.

python3 generate_dataset.py

After execution, you should see the confirmation.

✅ Dataset saved to fraction_dataset.csv

Step 3: Model Architecture & Training

With our dataset ready, the next step is to train a machine learning model that can learn to solve fraction problems by predicting the correct result when given an expression.

1. Create a script to train the model.

nano train_model.py

Add the following code.

import pandas as pd
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, TimeDistributed
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
import pickle

# Load dataset
df = pd.read_csv('fraction_dataset.csv')

# Tokenizer (character-level)
tokenizer = Tokenizer(char_level=True)
tokenizer.fit_on_texts(df['problem'].tolist() + df['solution'].tolist())

vocab_size = len(tokenizer.word_index) + 1

# Convert to sequences
X_seq = tokenizer.texts_to_sequences(df['problem'].tolist())
y_seq = tokenizer.texts_to_sequences(df['solution'].tolist())

# Pad sequences
max_len = 20
X = pad_sequences(X_seq, maxlen=max_len, padding='post')
y = pad_sequences(y_seq, maxlen=max_len, padding='post')

# 📝 Reshape y for categorical output at each timestep
y = np.expand_dims(y, -1)

# Define correct sequence-to-sequence model
model = Sequential([
    Embedding(input_dim=vocab_size, output_dim=64, input_length=max_len),
    LSTM(128, return_sequences=True),  # 🔥 Important change here!
    TimeDistributed(Dense(vocab_size, activation='softmax'))  # 🔥 Predict vocab distribution at each timestep
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Callbacks
early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
checkpoint = ModelCheckpoint('best_fraction_solver_model.h5', save_best_only=True)

# 🚀 Train for 30 epochs
history = model.fit(
    X, y,
    epochs=30,
    batch_size=64,
    validation_split=0.1,
    callbacks=[early_stop, checkpoint]
)

# Save tokenizer for inference
with open('tokenizer.pkl', 'wb') as f:
    pickle.dump(tokenizer, f)

print("✅ Training complete. Best model saved as best_fraction_solver_model.h5")

This script trains a character-level LSTM model to predict solutions for fraction problems. It tokenizes and pads input-output text, then uses a TimeDistributed layer for character prediction. The trained model and tokenizer are saved for later use.

2. Run the script.

python3 train_model.py

Output.

✅ Training complete. Best model saved as best_fraction_solver_model.h5

Step 4: Building the Flask Web Interface

After training our machine learning model, we aim to provide a straightforward way for users to input fraction problems and receive solutions through a simple web interface. Flask is a lightweight web framework that makes this straightforward.

1. Create the Flask application script.

nano app.py

Add the following code.

from flask import Flask, request, render_template_string
from fractions import Fraction
import re

app = Flask(__name__)

TEMPLATE = '''
<!doctype html>
<title>Hybrid Fraction Solver</title>
<h2>Fraction Problem Solver (Hybrid: ML UI + Exact Backend)</h2>
<form method=post>
  Enter fraction problem (e.g. 1/2 + 1/3): <input type=text name=problem>
  <input type=submit value=Solve>
</form>
{% if solution %}
  <h3>Solution: {{ solution }}</h3>
{% endif %}
'''

def solve_fraction_expression(expr):
    # Basic sanitization: remove spaces
    expr = expr.replace(' ', '')

    # Regex to extract operands and operator
    pattern = r'(\d+/\d+)([\+\-\*/])(\d+/\d+)'
    match = re.match(pattern, expr)

    if not match:
        return "Invalid input format"

    frac1, op, frac2 = match.groups()

    try:
        f1 = Fraction(frac1)
        f2 = Fraction(frac2)

        if op == '+':
            result = f1 + f2
        elif op == '-':
            result = f1 - f2
        elif op == '*':
            result = f1 * f2
        elif op == '/':
            if f2 == 0:
                result = "undefined"
            else:
                result = f1 / f2
        else:
            result = "Invalid operator"

        return str(result)

    except Exception as e:
        return f"Error: {str(e)}"

@app.route('/', methods=['GET', 'POST'])
def index():
    solution = None
    if request.method == 'POST':
        problem = request.form['problem']
        solution = solve_fraction_expression(problem)
    return render_template_string(TEMPLATE, solution=solution)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

2. Run the Flask application.

python3 app.py

Output.

 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://45.76.67.103:5000
Press CTRL+C to quit

Step 5: Access the Flask App

1. Open your web browser and access the Flask app using the URL http://your-server-ip:5000. You will be greeted with a simple but functional web form.

2. Enter a fraction problem (e.g., 3/4 + 4/7).

3. Click the Solve button.

4. The page will refresh and display the exact solution below the form.

Conclusion

In this article, we created a fraction problem solver by combining machine learning and traditional Python arithmetic, deployed on an Ubuntu 24.04 cloud GPU server. We generated a large dataset of fraction problems, trained a sequence-to-sequence model, and built a simple Flask web interface for user interaction. While the current version computes exact solutions on the backend, the system is ready for integration with the trained model for prediction-based solving.