Spaces:
Sleeping
Sleeping
| import random | |
| from typing import List, Optional | |
| from viral_script_engine.personas.creator_profile import ( | |
| CreatorProfile, CreatorTier, PostingFrequency, | |
| ) | |
| _ALL_CRITIQUE_CLASSES = [ | |
| "hook_weakness", "cta_buried", "cta_weakness", "pacing_issue", | |
| "cultural_mismatch", "originality_low", "section_disorder", "retention_drop", | |
| ] | |
| _VOICE_POOL = [ | |
| "direct", "humorous", "educational", "regional", "relatable", | |
| "Hinglish", "aspirational", "casual", "storytelling", "data-driven", | |
| ] | |
| _NICHE_MATURITY_BY_TIER = { | |
| CreatorTier.BEGINNER: ["new_to_niche"], | |
| CreatorTier.GROWING: ["new_to_niche", "established_in_niche"], | |
| CreatorTier.ESTABLISHED: ["established_in_niche", "niche_authority"], | |
| CreatorTier.VERIFIED: ["niche_authority"], | |
| } | |
| _POSTING_FREQ_BY_TIER = { | |
| CreatorTier.BEGINNER: [PostingFrequency.RARE, PostingFrequency.REGULAR], | |
| CreatorTier.GROWING: [PostingFrequency.REGULAR, PostingFrequency.FREQUENT], | |
| CreatorTier.ESTABLISHED: [PostingFrequency.FREQUENT, PostingFrequency.DAILY], | |
| CreatorTier.VERIFIED: [PostingFrequency.FREQUENT, PostingFrequency.DAILY], | |
| } | |
| class ProfileGenerator: | |
| NICHES = [ | |
| "personal finance", "cooking", "fitness", "tech reviews", | |
| "small business", "agriculture", "fashion", "comedy", | |
| "productivity", "travel", "education", "local culture", | |
| ] | |
| def generate(self, tier: CreatorTier, niche: str, seed: int = 42) -> CreatorProfile: | |
| rng = random.Random(seed) | |
| follower_count = self._follower_count(tier, rng) | |
| engagement_rate = self._engagement_rate(tier, rng) | |
| retention_rate = round(rng.uniform(0.25, 0.65), 3) | |
| posting_freq = rng.choice(_POSTING_FREQ_BY_TIER[tier]) | |
| niche_maturity = rng.choice(_NICHE_MATURITY_BY_TIER[tier]) | |
| voice = rng.sample(_VOICE_POOL, k=rng.randint(2, 4)) | |
| platform = rng.choice(["Reels", "Shorts", "TikTok"]) | |
| weak_pool = list(_ALL_CRITIQUE_CLASSES) | |
| weak_points = rng.sample(weak_pool, k=rng.randint(1, 3)) | |
| remaining = [c for c in weak_pool if c not in weak_points] | |
| strong_points = rng.sample(remaining, k=min(2, len(remaining))) | |
| creator_id = f"{tier.value}_{niche.replace(' ', '_')}_{seed}" | |
| return CreatorProfile( | |
| creator_id=creator_id, | |
| tier=tier, | |
| follower_count=follower_count, | |
| posting_frequency=posting_freq, | |
| niche=niche, | |
| niche_maturity=niche_maturity, | |
| avg_engagement_rate=engagement_rate, | |
| avg_retention_rate=retention_rate, | |
| past_weak_points=weak_points, | |
| past_strong_points=strong_points, | |
| voice_descriptors=voice, | |
| platform_primary=platform, | |
| ) | |
| def generate_batch(self, n: int, tier_distribution: Optional[dict] = None) -> List[CreatorProfile]: | |
| if tier_distribution is None: | |
| tier_distribution = { | |
| CreatorTier.BEGINNER: 0.40, | |
| CreatorTier.GROWING: 0.35, | |
| CreatorTier.ESTABLISHED: 0.20, | |
| CreatorTier.VERIFIED: 0.05, | |
| } | |
| tiers = list(tier_distribution.keys()) | |
| weights = [tier_distribution[t] for t in tiers] | |
| profiles = [] | |
| rng = random.Random(99) | |
| for i in range(n): | |
| tier = rng.choices(tiers, weights=weights, k=1)[0] | |
| niche = rng.choice(self.NICHES) | |
| profiles.append(self.generate(tier=tier, niche=niche, seed=i)) | |
| return profiles | |
| # --- private helpers --- | |
| def _follower_count(self, tier: CreatorTier, rng: random.Random) -> int: | |
| ranges = { | |
| CreatorTier.BEGINNER: (50, 999), | |
| CreatorTier.GROWING: (1000, 9999), | |
| CreatorTier.ESTABLISHED: (10000, 99999), | |
| CreatorTier.VERIFIED: (100000, 2000000), | |
| } | |
| lo, hi = ranges[tier] | |
| return rng.randint(lo, hi) | |
| def _engagement_rate(self, tier: CreatorTier, rng: random.Random) -> float: | |
| ranges = { | |
| CreatorTier.BEGINNER: (0.08, 0.15), | |
| CreatorTier.GROWING: (0.04, 0.08), | |
| CreatorTier.ESTABLISHED: (0.02, 0.04), | |
| CreatorTier.VERIFIED: (0.01, 0.02), | |
| } | |
| lo, hi = ranges[tier] | |
| return round(rng.uniform(lo, hi), 4) | |