Spaces:
Running
Running
File size: 6,026 Bytes
bfc1cf6 2f3d61a bfc1cf6 2f3d61a 516fc47 2f3d61a 516fc47 bfc1cf6 516fc47 109daa0 516fc47 2f3d61a bfc1cf6 516fc47 e6857f6 516fc47 bfc1cf6 2f3d61a 516fc47 2f3d61a bfc1cf6 2f3d61a bfc1cf6 516fc47 bfc1cf6 516fc47 ef21c2f bfc1cf6 516fc47 bfc1cf6 516fc47 bfc1cf6 516fc47 bfc1cf6 516fc47 bfc1cf6 2f3d61a 91aaf8c 2f3d61a 91aaf8c 2f3d61a |
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 |
import os
import gradio as gr
from anthropic import Anthropic
from datetime import datetime, timedelta
from collections import deque
import random
# Initialize Anthropic client
anthropic = Anthropic(
api_key=os.environ.get('ANTHROPIC_API_KEY')
)
# Request tracking
MAX_REQUESTS_PER_DAY = 25
request_history = deque(maxlen=1000)
def check_api_key():
"""Verify API key is configured"""
if not os.environ.get('ANTHROPIC_API_KEY'):
raise ValueError("Anthropic API key not found. Please configure it in HuggingFace Spaces settings.")
def check_rate_limit():
"""Check if we're within rate limits"""
now = datetime.now()
while request_history and (now - request_history[0]) > timedelta(days=1):
request_history.popleft()
return len(request_history) < MAX_REQUESTS_PER_DAY
def clean_latex(text):
"""Simple LaTeX cleaning"""
text = text.replace('\n', '\n\n')
return text
def generate_test(subject):
"""Generate a math test with enhanced variety"""
try:
check_api_key()
if not check_rate_limit():
return "Daily request limit reached. Please try again tomorrow."
request_history.append(datetime.now())
# Randomly select focus areas and difficulty levels
topics = {
"Single Variable Calculus": ["limits", "derivatives", "integrals", "series", "applications"],
"Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization", "surface integrals"],
"Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations", "inner products"],
# ... add topics for other subjects
}
selected_topics = random.sample(topics.get(subject, ["general"]), min(3, len(topics.get(subject, ["general"]))))
difficulty_distribution = random.choice([
"one easy, one medium, one challenging",
"two medium, one very challenging",
"one medium, two challenging"
])
system_prompt = f"""You will write math exam questions. Follow these requirements EXACTLY:
1. Write exactly 3 university-level questions focusing on these specific topics: {', '.join(selected_topics)}
2. Make the questions {difficulty_distribution}
3. For each question, use a different type of mathematical thinking (e.g., computation, proof, application, conceptual understanding)
4. Ensure questions are unique and not commonly found in textbooks
5. For LaTeX math formatting:
- Use $ for simple inline math
- For equations and solution steps, use $$ on separate lines
- For multi-step solutions, put each step on its own line in $$ $$
- DO NOT use \\begin{{aligned}} or any other environments
6. Number each question as 1), 2), 3)
7. Include detailed solutions after each question
8. Keep formatting simple and clear
Important: Make these questions distinct from standard textbook problems. Incorporate real-world applications,
interdisciplinary connections, or creative scenarios where appropriate."""
# Vary temperature based on subject complexity
base_temperature = 0.7
complexity_adjustment = random.uniform(-0.1, 0.1)
temperature = min(1.0, max(0.5, base_temperature + complexity_adjustment))
message = anthropic.messages.create(
model="claude-3-opus-20240229",
max_tokens=1500,
temperature=temperature,
messages=[{
"role": "user",
"content": f"{system_prompt}\n\nWrite an exam for {subject}."
}]
)
# Extract usage information
input_tokens = message.usage.input_tokens
output_tokens = message.usage.output_tokens
input_cost = (input_tokens / 1000) * 0.015
output_cost = (output_tokens / 1000) * 0.075
total_cost = input_cost + output_cost
usage_stats = f"""
\n---\nUsage Statistics:
• Input Tokens: {input_tokens:,}
• Output Tokens: {output_tokens:,}
• Total Tokens: {input_tokens + output_tokens:,}
Cost Breakdown:
• Input Cost: ${input_cost:.4f}
• Output Cost: ${output_cost:.4f}
• Total Cost: ${total_cost:.4f}
"""
if hasattr(message, 'content') and len(message.content) > 0:
response_text = message.content[0].text
formatted_response = clean_latex(response_text) + usage_stats
return formatted_response
else:
return "Error: No content in response"
except ValueError as e:
return f"Configuration Error: {str(e)}"
except Exception as e:
return f"Error: {str(e)}"
# Subject choices remain the same
subjects = [
"Single Variable Calculus",
"Multivariable Calculus",
"Linear Algebra",
"Differential Equations",
"Real Analysis",
"Complex Analysis",
"Abstract Algebra",
"Probability Theory",
"Numerical Analysis",
"Topology"
]
# Create Gradio interface
interface = gr.Interface(
fn=generate_test,
inputs=gr.Dropdown(
choices=subjects,
label="Select Mathematics Subject",
info="Choose a subject for the exam questions"
),
outputs=gr.Markdown(
label="Generated Test",
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True},
{"left": "$", "right": "$", "display": False}
]
),
title="Advanced Mathematics Test Generator",
description="""Generates unique university-level mathematics exam questions with solutions using Claude 3 Opus.
Each test features different topics and difficulty levels. Limited to 25 requests per day.""",
theme="default",
allow_flagging="never"
)
if __name__ == "__main__":
interface.launch() |