Skip to content

Commit

Permalink
Update index.qmd
Browse files Browse the repository at this point in the history
  • Loading branch information
awellis committed Nov 28, 2024
1 parent b295fa3 commit 6ba2d28
Showing 1 changed file with 156 additions and 0 deletions.
156 changes: 156 additions & 0 deletions projects/anki/example/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,166 @@ jupyter: python3
```{python}
from dotenv import load_dotenv # For loading environment variables
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import List
```

```{python}
load_dotenv()
client = OpenAI()
```

```{python}
class AnkiFlashcard(BaseModel):
"""
Model representing a single Anki flashcard with question, answer, and tags.
"""
# Define required fields with descriptions
question: str = Field(..., description="The front side of the flashcard containing the question")
answer: str = Field(..., description="The back side of the flashcard containing the answer")
tags: List[str] = Field(..., description="List of tags associated with the flashcard")
```

```{python}
class AnkiDeck(BaseModel):
"""
Model representing a complete Anki deck containing multiple flashcards.
"""
# Define required fields with descriptions
cards: List[AnkiFlashcard] = Field(..., description="List of flashcards in the deck")
deck_name: str = Field(..., description="Name of the Anki deck")
```

```{python}
def generate_structured_flashcards(text: str, deck_name: str, num_cards: int = 5) -> AnkiDeck:
"""
Generate structured flashcards using GPT-4o with enforced Pydantic model output.
Args:
text (str): The input text to generate flashcards from
deck_name (str): Name for the Anki deck
num_cards (int): Number of flashcards to generate (default: 5)
Returns:
AnkiDeck: A structured deck of flashcards with proper validation
Raises:
ValueError: If num_cards is less than 1
"""
# Validate input
if num_cards < 1:
raise ValueError("Number of cards must be at least 1")
# Make API call with structured output format
completion = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{
"role": "system",
"content": f"""You are an expert at creating Anki flashcards. Your task is to:
1. Read the provided text
2. Create {num_cards} Anki flashcards that cover the main concepts
3. Add relevant tags to each flashcard
4. Structure the output as an Anki deck with the name "{deck_name}"."""
},
{
"role": "user",
"content": f"Please create Anki flashcards for the following text: {text}"
}
],
response_format=AnkiDeck,
)
# Return the parsed response
return completion.choices[0].message.parsed
```


```{python}
#| echo: false
with open("romantic-essay.md", "r") as file:
romantic_text = file.read()
```

:::{.callout-note collapse=true title="`romantic_text`"}
## The Romantic Era: Emotion Unleashed (1810-1910)

The Romantic era represented a dramatic shift in musical aesthetics, prioritizing emotional expression, individualism, and nationalism over the formal constraints of the Classical period. This century-long period saw an unprecedented expansion in the scope, scale, and emotional range of classical music.

### The Romantic Spirit

Romanticism emerged as a reaction against the rationalism of the Enlightenment and the Industrial Revolution. Composers sought to express intense personal emotions, explore supernatural themes, and celebrate national identity through music. This new aesthetic led to the development of program music - compositions that told specific stories or painted musical pictures.

### Expansion of Musical Language

The Romantic period saw a significant expansion of harmonic language. Composers pushed the boundaries of chromatic harmony, using increasingly complex chord progressions and modulations to distant keys. This development reached its apex in Wagner's "Tristan und Isolde," whose famous "Tristan chord" symbolized the dissolution of traditional tonality.

### The Symphony Transformed

The symphony, inherited from the Classical era, underwent radical transformation. Beethoven's Ninth Symphony, with its unprecedented scale and inclusion of vocal soloists and chorus, set new standards for symphonic composition. Later composers like Berlioz, Mahler, and Bruckner created symphonies of enormous proportions, both in length and orchestral forces.

### New Forms and Genres

The period saw the emergence of new musical forms suited to Romantic expression. The symphonic poem, developed by Franz Liszt, combined orchestral music with extra-musical narratives. The art song (Lied) reached new heights of sophistication in the hands of Schubert and Schumann, creating perfect unions of poetry and music.

### Nationalism in Music

National schools of composition emerged as countries sought to express their cultural identity through music. Russian composers like Tchaikovsky and the "Mighty Five" incorporated folk melodies and national themes. Similar movements appeared in Bohemia (Smetana, Dvořák), Norway (Grieg), and other European nations.

### The Rise of the Virtuoso

The Romantic era celebrated individual achievement, leading to the rise of the virtuoso performer. Pianists like Liszt and Chopin composed works of unprecedented technical difficulty, while violinists like Paganini pushed the boundaries of what was possible on their instrument. This emphasis on virtuosity influenced compositional style and public performance practices.

### Wagner and Music Drama

Richard Wagner revolutionized opera through his concept of Gesamtkunstwerk (total artwork), combining music, drama, poetry, and visual arts. His use of leitmotifs - recurring musical themes associated with characters, objects, or ideas - influenced not only opera but also symphonic composition and, later, film music.

### Technical and Social Developments

The period saw significant developments in instrument construction. The modern piano reached its current form, while brass instruments benefited from the invention of valves. Orchestras grew larger, requiring the emergence of the conductor as an interpreter rather than merely a timekeeper.

### The End of an Era

The Romantic period gradually gave way to various modern movements. The increasing chromatic harmony of late Romanticism led naturally to the breakdown of traditional tonality in the early 20th century. However, Romantic ideals of emotional expression and individualism continued to influence composers well into the modern era.

The Romantic era's emphasis on emotional expression, its technical innovations, and its expansion of musical possibilities created a legacy that continues to influence musicians today. The period's great works remain central to the concert repertoire, beloved for their emotional depth and expressive power.
:::

```{python}
print(romantic_text)
```


```{python}
romantic_deck = generate_structured_flashcards(romantic_text, "Romanticism", 10)
```

```{python}
romantic_deck
```

```{python}
print(romantic_deck.model_dump_json())
```

```{python}
for card in romantic_deck.cards:
print(f"Question: {card.question}")
print(f"Answer: {card.answer}")
print(f"Tags: {', '.join(card.tags)}")
print("-" * 20)
```

```{python}
os.makedirs('assets/flashcards', exist_ok=True)
# Export flashcards to CSV file
with open('assets/flashcards/romantic-flashcards.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
# Write header row
writer.writerow(['Question', 'Answer', 'Tags'])
# Write each flashcard as a row in the CSV
for card in romantic_deck.cards:
writer.writerow([card.question, card.answer, ', '.join(card.tags)])
```

0 comments on commit 6ba2d28

Please sign in to comment.