Spaces:
Sleeping
Sleeping
File size: 13,088 Bytes
a4936fb |
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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# suppress warnings
import warnings
warnings.filterwarnings("ignore")
# import libraries
import argparse
from together import Together
import textwrap
import os
from datetime import datetime
import gradio as gr
# Parse command line arguments
parser = argparse.ArgumentParser(description="AI Study Tool")
parser.add_argument(
"--together_api_key",
"-k",
default="9806a2601560024637df1e4acd804862faa67e08637db6598d920b64eebba43e",
help="Together AI API key",
)
args = parser.parse_args()
# Initialize client with API key
client = Together(api_key=args.together_api_key)
# Add the cats content as a constant string
CATS_CONTENT = """The cat (Felis catus), also referred to as the domestic cat or house cat, is a small domesticated carnivorous mammal. It is the only domesticated species of the family Felidae. Advances in archaeology and genetics have shown that the domestication of the cat occurred in the Near East around 7500 BC. It is commonly kept as a pet and working cat, but also ranges freely as a feral cat avoiding human contact. It is valued by humans for companionship and its ability to kill vermin. Its retractable claws are adapted to killing small prey species such as mice and rats. It has a strong, flexible body, quick reflexes, and sharp teeth, and its night vision and sense of smell are well developed. It is a social species, but a solitary hunter and a crepuscular predator.
Cat intelligence is evident in their ability to adapt, learn through observation, and solve problems. Research has shown they possess strong memories, exhibit neuroplasticity, and display cognitive skills comparable to those of a young child. Cat communication includes meowing, purring, trilling, hissing, growling, grunting, and body language. It can hear sounds too faint or too high in frequency for human ears, such as those made by small mammals. It secretes and perceives pheromones.
Female domestic cats can have kittens from spring to late autumn in temperate zones and throughout the year in equatorial regions, with litter sizes often ranging from two to five kittens. Domestic cats are bred and shown at cat fancy events as registered pedigreed cats. Population control includes spaying and neutering, but pet abandonment has exploded the global feral cat population, which has driven the extinction of bird, mammal, and reptile species.
Domestic cats are found across the globe, though their popularity as pets varies by region. Out of the estimated 600 million cats worldwide, 400 million reside in Asia, including 58 million pet cats in China. The United States leads in cat ownership with 73.8 million cats. In the United Kingdom, approximately 10.9 million domestic cats are kept as pets.
Etymology and naming
The origin of the English word cat, Old English catt, is thought to be the Late Latin word cattus, which was first used at the beginning of the 6th century.[4] The Late Latin word may be derived from an unidentified African language.[5] The Nubian word kaddîska (wildcat) and Nobiin kadīs are possible sources or cognates.[6]
The forms might also have derived from an ancient Germanic word that was absorbed into Latin and then into Greek, Syriac, and Arabic.[7] The word may be derived from Germanic and Northern European languages, and ultimately be borrowed from Uralic, cf. Northern Sámi gáđfi, female stoat, and Hungarian hölgy, lady, female stoat; from Proto-Uralic *käďwä, female (of a furred animal).[8]
The English puss, extended as pussy and pussycat, is attested from the 16th century and may have been introduced from Dutch poes or from Low German puuskatte, related to Swedish kattepus, or Norwegian pus, pusekatt. Similar forms exist in Lithuanian puižė and Irish puisín or puiscín. The etymology is unknown, but it may be an onomatopoeia from using a sound to attract a cat.[9][10]
A male cat is called a tom or tomcat[11] (or a gib,[12] if neutered). A female is called a queen.[13] Some sources write that queen refers solely to unspayed cats that are in an estrous cycle.[14] (or sometimes a molly,[15] if spayed). A juvenile cat is referred to as a kitten, a term interchangeable with the now-obsolete word catling in Early Modern English.[16] A group of cats can be referred to as a clowder, a glaring,[17] or a colony.[18]
Taxonomy
The scientific name Felis catus was proposed by Carl Linnaeus in 1758 for a domestic cat.[1][2] Felis catus domesticus was proposed by Johann Christian Polycarp Erxleben in 1777.[3] Felis daemon proposed by Konstantin Satunin in 1904 was a black cat from the Transcaucasus, later identified as a domestic cat.[19][20]
In 2003, the International Commission on Zoological Nomenclature ruled that the domestic cat is a distinct species, namely Felis catus.[21][22] In 2007, the modern domesticated subspecies F. silvestris catus sampled worldwide was considered to have probably descended from the African wildcat (F. lybica), following results of phylogenetic research.[23][24][a] In 2017, the IUCN Cat Classification Taskforce followed the recommendation of the ICZN in regarding the domestic cat as a distinct species, Felis catus.[25]"""
## FUNCTION 1: This Allows Us to Prompt the AI MODEL
# -------------------------------------------------
def prompt_llm(prompt, with_linebreak=False):
# This function allows us to prompt an LLM via the Together API
# model
model = "meta-llama/Meta-Llama-3-8B-Instruct-Lite"
# Make the API call
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
output = response.choices[0].message.content
if with_linebreak:
# Wrap the output
wrapped_output = textwrap.fill(output, width=50)
return wrapped_output
else:
return output
## FUNCTION 2: Load text file content
# -------------------------------------------------
def load_file(filepath):
"""Load content from a text file"""
try:
with open(filepath, "r", encoding="utf-8") as file:
return file.read()
except FileNotFoundError:
print(f"Error: File {filepath} not found.")
return None
except Exception as e:
print(f"Error reading file: {e}")
return None
## FUNCTION 3: Generate bite-sized concept summaries
# -------------------------------------------------
def summarize_concepts(text_content):
"""Generate bite-sized 2-sentence concepts from text content"""
prompt = f"""
Please analyze the following text and break it down into bite-sized learning concepts.
For each concept, provide exactly 2 sentences that capture the key idea in a clear,
easy-to-understand way suitable for studying.
Format each concept as:
Concept X: [2 sentences explaining the concept]
Text to analyze:
{text_content}
"""
return prompt_llm(prompt)
## FUNCTION 4: Save results to timestamped file
# -------------------------------------------------
def save_results(content, output_dir="results"):
"""Save content to a timestamped file in the results directory"""
# Create results directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)
# Generate timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}.txt"
filepath = os.path.join(output_dir, filename)
# Save content
try:
with open(filepath, "w", encoding="utf-8") as file:
file.write(content)
print(f"Results saved to: {filepath}")
return filepath
except Exception as e:
print(f"Error saving file: {e}")
return None
## FUNCTION 5: Create Gradio Interface
# -------------------------------------------------
def create_gradio_interface():
"""Create a Gradio interface for the study tool"""
def process_file_and_generate_content():
"""Process the cats content and generate study content"""
try:
# Use the hardcoded content instead of loading from file
content = CATS_CONTENT
# Generate summaries
summaries = summarize_concepts(content)
# Parse summaries into individual concepts - improved parsing for **Concept X:** format
concepts = []
# Split by **Concept and filter out empty parts
parts = summaries.split("**Concept")
for i, part in enumerate(parts):
if i == 0: # Skip the intro text before first concept
continue
# Clean up the part and add back "Concept" prefix
concept_text = "Concept" + part.strip()
# Remove the closing ** if present
if concept_text.endswith("**"):
concept_text = concept_text[:-2].strip()
# Remove any ** formatting within the text
concept_text = concept_text.replace("**", "")
if concept_text:
concepts.append(concept_text)
# Save results
save_results(f"BITE-SIZED CONCEPT SUMMARIES:\n{summaries}")
# Return first concept for immediate display
first_concept = concepts[0] if concepts else "No concepts generated."
return (
f"Content processed successfully! Found {len(concepts)} concepts. Navigate through them below.",
summaries,
concepts,
0, # current concept index
first_concept, # display first concept immediately
)
except Exception as e:
return f"Error processing content: {str(e)}", "", [], 0, "Error occurred."
def navigate_concept(concepts, current_idx, direction):
"""Navigate through concepts (previous/next)"""
if not concepts:
return "No concepts available.", 0
if direction == "next":
new_idx = min(current_idx + 1, len(concepts) - 1)
else: # previous
new_idx = max(current_idx - 1, 0)
concept_text = (
concepts[new_idx] if new_idx < len(concepts) else "No concept available."
)
return concept_text, new_idx
# Create Gradio interface
with gr.Blocks(title="AI Study Tool", theme=gr.themes.Soft()) as interface:
gr.Markdown("# 📚 AI Study Tool")
gr.Markdown("Generate bite-sized concepts from cat information for studying!")
# Process button section
with gr.Row():
process_btn = gr.Button("Process Cat Content", variant="primary")
# Status and results
status_output = gr.Textbox(label="Status", interactive=False)
# Hidden state variables
full_summaries = gr.State("")
concepts_list = gr.State([])
current_concept_idx = gr.State(0)
# Concept navigation section
with gr.Row():
gr.Markdown("## 🧠 Study Concepts")
with gr.Row():
prev_btn = gr.Button("← Previous Concept")
concept_counter = gr.Textbox(
label="Concept Position", interactive=False, value="0 / 0"
)
next_btn = gr.Button("Next Concept →")
concept_display = gr.Textbox(
label="Current Concept",
lines=4,
interactive=False,
placeholder="Process a file to see concepts here...",
)
# Event handlers
process_btn.click(
fn=process_file_and_generate_content,
inputs=[],
outputs=[
status_output,
full_summaries,
concepts_list,
current_concept_idx,
concept_display,
],
).then(
fn=lambda concepts, idx: (
f"{idx + 1} / {len(concepts)}" if concepts else "0 / 0"
),
inputs=[concepts_list, current_concept_idx],
outputs=[concept_counter],
)
prev_btn.click(
fn=lambda concepts, idx: navigate_concept(concepts, idx, "previous"),
inputs=[concepts_list, current_concept_idx],
outputs=[concept_display, current_concept_idx],
).then(
fn=lambda concepts, idx: (
f"{idx + 1} / {len(concepts)}" if concepts else "0 / 0"
),
inputs=[concepts_list, current_concept_idx],
outputs=[concept_counter],
)
next_btn.click(
fn=lambda concepts, idx: navigate_concept(concepts, idx, "next"),
inputs=[concepts_list, current_concept_idx],
outputs=[concept_display, current_concept_idx],
).then(
fn=lambda concepts, idx: (
f"{idx + 1} / {len(concepts)}" if concepts else "0 / 0"
),
inputs=[concepts_list, current_concept_idx],
outputs=[concept_counter],
)
return interface
if __name__ == "__main__":
# Launch Gradio interface
interface = create_gradio_interface()
interface.launch()
|