এই সাইটটি বার পঠিত
ভাটিয়ালি | টইপত্তর | বুলবুলভাজা | হরিদাস পাল | খেরোর খাতা | বই
  • টইপত্তর  আলোচনা  রাজনীতি

  • INDIAN ADVANCED PREFERENTIAL VOTING SYSTEM

    albert banerjee লেখকের গ্রাহক হোন
    আলোচনা | রাজনীতি | ১৪ মার্চ ২০২৬ | ৪২ বার পঠিত
  • A comprehensive voting system simulating Indian electoral dynamics

    import math
    import random
    import json
    from datetime import datetime
    from collections import defaultdict
    from typing import List, Dict, Tuple, Optional
    from enum import Enum
    import time

     ==================== ENUMS for Indian Context ====================

    class CasteCategory(Enum):
        """Indian caste categories for demographic analysis"""
        GENERAL = "General"
        OBC = "OBC"
        SC = "SC"
        ST = "ST"
        MINORITY = "Minority"

    class Religion(Enum):
        """Religious demographics of India"""
        HINDU = "Hindu"
        MUSLIM = "Muslim"
        SIKH = "Sikh"
        CHRISTIAN = "Christian"
        BUDDHIST = "Buddhist"
        JAIN = "Jain"
        OTHER = "Other"

    class Region(Enum):
        """Different regions of India with voting behaviors"""
        NORTH = "North India"
        SOUTH = "South India"
        EAST = "East India"
        WEST = "West India"
        CENTRAL = "Central India"
        NORTHEAST = "Northeast India"

    class UrbanRural(Enum):
        """Urban-Rural classification"""
        METRO = "Metro City"
        URBAN = "Urban"
        SEMI_URBAN = "Semi-Urban"
        RURAL = "Rural"

    class Language(Enum):
        """Major Indian languages"""
        HINDI = "Hindi"
        BENGALI = "Bengali"
        TELUGU = "Telugu"
        MARATHI = "Marathi"
        TAMIL = "Tamil"
        URDU = "Urdu"
        GUJARATI = "Gujarati"
        KANNADA = "Kannada"
        MALAYALAM = "Malayalam"
        ORIYA = "Odiya"
        PUNJABI = "Punjabi"
        ASSAMESE = "Assamese"
        OTHER = "Other"

    class VotingBehavior(Enum):
        """Voter behavior patterns"""
        CASTE_BASED = "Caste Based"
        COMMUNITY_BASED = "Community Based"
        DEVELOPMENT_BASED = "Development Based"
        LEADER_BASED = "Leader Based"
        PARTY_BASED = "Party Based"
        ISSUE_BASED = "Issue Based"
        DYNASTY_BASED = "Dynasty Based"
        MONEY_BASED = "Money Based"
        FAMILY_TRADITION = "Family Tradition"

    class AllianceType(Enum):
        """Political alliance types in India"""
        PRE_POLL = "Pre-Poll Alliance"
        POST_POLL = "Post-Poll Alliance"
        SEAT_SHARING = "Seat Sharing"
        IDEOLOGICAL = "Ideological"
        OPPORTUNISTIC = "Opportunistic"
        REGIONAL_FRONT = "Regional Front"
        NATIONAL_FRONT = "National Front"

    class ElectionLevel(Enum):
        """Levels of elections in India"""
        PANCHAYAT = "Panchayat"
        MUNICIPAL = "Municipal Corporation"
        VIDHAN_SABHA = "Vidhan Sabha (State Assembly)"
        LOK_SABHA = "Lok Sabha (Parliament)"
        RAJYA_SABHA = "Rajya Sabha (Council of States)"

     ==================== MAIN VOTING SYSTEM CLASS ====================

    class IndianVotingSystem:
        """
        Advanced Indian Preferential Voting System with:
        - Multi-tiered vote counting (Panchayat to Parliament)
        - Caste and community vote bank analysis
        - Coalition and alliance management
        - NOTA (None of The Above) handling
        - EVM and Postal ballot simulation
        - Booth-level dynamics
        - Swing voter analysis
        - Anti-defection law simulation
        """
       
        def __init__(self,
                     election_name: str,
                     election_level: ElectionLevel = ElectionLevel.LOK_SABHA,
                     state: str = "National",
                     constituency_name: str = "General",
                     total_seats: int = 1,
                     quota_type: str = "droop",
                     use_nota: bool = True,
                     enable_alliances: bool = True,
                     demographic_analysis: bool = True):
            """
            Initialize the Indian Voting System
           
            Parameters:
            - election_name: Name of the election
            - election_level: Level of election (Panchayat to Lok Sabha)
            - state: State where election is held
            - constituency_name: Name of constituency
            - total_seats: Number of seats to fill
            - quota_type: Type of quota ('droop', 'hare', 'imperiali')
            - use_nota: Enable NOTA option
            - enable_alliances: Enable political alliances
            - demographic_analysis: Enable demographic analysis
            """
           
            self.election_name = election_name
            self.election_level = election_level.value
            self.state = state
            self.constituency_name = constituency_name
            self.total_seats = total_seats
            self.quota_type = quota_type
            self.use_nota = use_nota
            self.enable_alliances = enable_alliances
            self.demographic_analysis = demographic_analysis
           
             Data structures
            self.candidates = {}
            self.parties = {}
            self.alliances = {}
            self.booths = []
            self.ballots = []
            self.postal_ballots = []
            self.rounds = []
           
             Tracking
            self.voter_demographics = []
            self.caste_vote_shares = defaultdict(dict)
            self.swing_voters = 0
            self.nota_votes = 0
            self.total_voters = 0
            self.turnout_percentage = 0
           
             Election commission data
            self.ec_observers = []
            self.evm_malfunctions = 0
            self.re_poll_booths = []
           
            self._print_header()
       
        def _print_header(self):
            """Print election header"""
            print(f"\n{'='80}")
            print(f"INDIAN ADVANCED PREFERENTIAL VOTING SYSTEM")
            print(f"{'='80}")
            print(f"Election: {self.election_name}")
            print(f"Level: {self.election_level}")
            print(f"State: {self.state}")
            print(f"Constituency: {self.constituency_name}")
            print(f"Seats: {self.total_seats}")
            print(f"Quota Type: {self.quota_type}")
            print(f"NOTA Enabled: {self.use_nota}")
            print(f"Alliances Enabled: {self.enable_alliances}")
            print(f"{'='80}\n")
       
         ==================== PARTY MANAGEMENT ====================
       
        def add_party(self, party_id: str, name: str, symbol: str,
                      ideology: str, founded_year: int,
                      national_party: bool = False,
                      state_parties: List[str] = None):
            """
            Add a political party with detailed information
           
            Parameters:
            - party_id: Unique party identifier
            - name: Party name
            - symbol: Election symbol
            - ideology: Political ideology
            - founded_year: Year founded
            - national_party: Whether it's a national party
            - state_parties: List of state party units
            """
            self.parties[party_id] = {
                'name': name,
                'symbol': symbol,
                'ideology': ideology,
                'founded_year': founded_year,
                'national_party': national_party,
                'state_parties': state_parties or [],
                'alliances': [],
                'total_votes': 0,
                'seats_won': 0,
                'vote_share': 0,
                'candidates': []
            }
            print(f"  Party added: {name} ({symbol})")
            return self
       
         ==================== CANDIDATE MANAGEMENT ====================
       
        def add_candidate(self,
                         candidate_id: str,
                         name: str,
                         party_id: str,
                         constituency: str,
                         age: int,
                         education: str,
                         criminal_records: int = 0,
                         assets: float = 0.0,
                         liabilities: float = 0.0,
                         caste: CasteCategory = None,
                         religion: Religion = None,
                         local_resident: bool = True,
                         dynasty_legacy: bool = False,
                         incumbency: bool = False):
            """
            Add a candidate with comprehensive Indian political profile
           
            Parameters:
            - candidate_id: Unique candidate identifier
            - name: Candidate name
            - party_id: Party identifier
            - constituency: Constituency name
            - age: Candidate age
            - education: Educational qualification
            - criminal_records: Number of criminal cases
            - assets: Total assets in crores
            - liabilities: Total liabilities in crores
            - caste: Caste category
            - religion: Religion
            - local_resident: Whether resident of constituency
            - dynasty_legacy: Whether from political family
            - incumbency: Whether current office holder
            """
            if party_id not in self.parties:
                raise ValueError(f"Party {party_id} does not exist")
           
            self.candidates[candidate_id] = {
                'id': candidate_id,
                'name': name,
                'party_id': party_id,
                'party_name': self.parties[party_id]['name'],
                'constituency': constituency,
                'age': age,
                'education': education,
                'criminal_records': criminal_records,
                'assets': assets,
                'liabilities': liabilities,
                'caste': caste.value if caste else "Unknown",
                'religion': religion.value if religion else "Unknown",
                'local_resident': local_resident,
                'dynasty_legacy': dynasty_legacy,
                'incumbency': incumbency,
                'active': True,
                'elected_round': None,
                'eliminated_round': None,
                'vote_history': [],
                'margin': 0,
                'total_votes': 0
            }
           
            self.parties[party_id]['candidates'].append(candidate_id)
            print(f"  Candidate added: {name} ({self.parties[party_id]['name']})")
            return self
       
         ==================== ALLIANCE MANAGEMENT ====================
       
        def create_alliance(self, alliance_id: str, name: str,
                           alliance_type: AllianceType,
                           member_parties: List[str],
                           common_manifesto: str = "",
                           seat_sharing_agreement: Dict = None):
            """
            Create a political alliance (like NDA, UPA, etc.)
           
            Parameters:
            - alliance_id: Unique alliance identifier
            - name: Alliance name
            - alliance_type: Type of alliance
            - member_parties: List of party IDs in alliance
            - common_manifesto: Common agenda
            - seat_sharing_agreement: Seat distribution details
            """
            self.alliances[alliance_id] = {
                'name': name,
                'type': alliance_type.value,
                'member_parties': member_parties,
                'common_manifesto': common_manifesto,
                'seat_sharing_agreement': seat_sharing_agreement or {},
                'formation_date': datetime.now(),
                'votes_aggregate': 0,
                'seats_won': 0,
                'active': True
            }
           
             Register alliance in member parties
            for party_id in member_parties:
                if party_id in self.parties:
                    self.parties[party_id]['alliances'].append(alliance_id)
           
            alliance_type_name = alliance_type.value
            print(f"  Alliance created: {name} ({alliance_type_name})")
            print(f"     Members: {', '.join([self.parties[p]['name'] for p in member_parties])}")
            return self
       
         ==================== BOOTH MANAGEMENT ====================
       
        def add_booth(self, booth_id: str, name: str,
                     region: Region, urban_rural: UrbanRural,
                     total_voters: int,
                     demographics: Dict[CasteCategory, float],
                     religious_demographics: Dict[Religion, float],
                     language: Language,
                     historical_turnout: float = 0.7,
                     sensitive_booth: bool = False):
            """
            Add a polling booth with demographic data
           
            Parameters:
            - booth_id: Unique booth identifier
            - name: Booth name
            - region: Geographic region
            - urban_rural: Urban/Rural classification
            - total_voters: Total registered voters
            - demographics: Caste demographics (percentages)
            - religious_demographics: Religious demographics (percentages)
            - language: Primary language
            - historical_turnout: Historical voting percentage
            - sensitive_booth: Whether it's a sensitive booth
            """
             Validate demographics sum to 100%
            if abs(sum(demographics.values()) - 1.0) > 0.01:
                raise ValueError("Demographics must sum to 1.0")
            if abs(sum(religious_demographics.values()) - 1.0) > 0.01:
                raise ValueError("Religious demographics must sum to 1.0")
           
            self.booths.append({
                'id': booth_id,
                'name': name,
                'region': region.value,
                'urban_rural': urban_rural.value,
                'total_voters': total_voters,
                'demographics': {k.value: v for k, v in demographics.items()},
                'religious_demographics': {k.value: v for k, v in religious_demographics.items()},
                'language': language.value,
                'historical_turnout': historical_turnout,
                'sensitive_booth': sensitive_booth,
                'actual_turnout': 0,
                'evm_votes': {},
                'postal_votes': {},
                'nota_count': 0
            })
           
            self.total_voters += total_voters
            print(f"  Booth added: {name} ({region.value}, {urban_rural.value}) - {total_voters} voters")
            return self
       
         ==================== VOTER GENERATION ====================
       
        def generate_voters(self, num_voters: int = 10000):
            """
            Generate voters with realistic Indian demographic patterns
            """
            print(f"\nGenerating {num_voters} voters with realistic Indian demographics...")
           
            voters = []
           
             Distribute voters across booths proportionally
            total_booth_voters = sum(b['total_voters'] for b in self.booths)
           
            for booth in self.booths:
                 Calculate voters for this booth
                booth_voters_count = int((booth['total_voters'] / total_booth_voters)  num_voters)
               
                for i in range(booth_voters_count):
                     Determine caste based on booth demographics
                    caste = random.choices(
                        list(booth['demographics'].keys()),
                        weights=list(booth['demographics'].values())
                    )[0]
                    
                     Determine religion
                    religion = random.choices(
                        list(booth['religious_demographics'].keys()),
                        weights=list(booth['religious_demographics'].values())
                    )[0]
                    
                     Determine voting behavior (weighted for Indian context)
                    behavior = self._determine_voting_behavior(caste, religion, booth)
                   
                     Generate preference order
                    preferences = self._generate_preferences(
                        behavior, caste, religion, booth
                    )
                   
                    voter = {
                        'id': f"V{len(voters)+1:06d}",
                        'booth_id': booth['id'],
                        'caste': caste,
                        'religion': religion,
                        'behavior': behavior.value,
                        'preferences': preferences,
                        'weight': 1.0,
                        'voted': False,
                        'postal': False,
                        'swing_voter': False
                    }
                   
                    voters.append(voter)
           
             Add swing voters (5-10%)
            swing_percentage = random.uniform(0.05, 0.10)
            num_swing = int(num_voters  swing_percentage)
            swing_indices = random.sample(range(len(voters)), num_swing)
           
            for idx in swing_indices:
                voters[idx]['swing_voter'] = True
                voters[idx]['swing_factor'] = random.uniform(0.5, 1.5)
           
            self.voter_demographics = voters
            self.swing_voters = num_swing
           
            print(f"  Generated {len(voters)} voters")
            print(f"  Swing voters: {num_swing} ({swing_percentage100:.1f}%)")
            return voters
       
        def _determine_voting_behavior(self, caste: str, religion: str,
                                      booth: Dict) -> VotingBehavior:
            """Determine voting behavior based on demographics"""
           
             Behavior weights for Indian context
            weights = {
                VotingBehavior.CASTE_BASED: 0.30,
                VotingBehavior.COMMUNITY_BASED: 0.20,
                VotingBehavior.DEVELOPMENT_BASED: 0.15,
                VotingBehavior.LEADER_BASED: 0.12,
                VotingBehavior.PARTY_BASED: 0.10,
                VotingBehavior.ISSUE_BASED: 0.05,
                VotingBehavior.DYNASTY_BASED: 0.03,
                VotingBehavior.MONEY_BASED: 0.03,
                VotingBehavior.FAMILY_TRADITION: 0.02
            }
           
             Adjust based on urban/rural
            if booth['urban_rural'] in [UrbanRural.METRO.value, UrbanRural.URBAN.value]:
                weights[VotingBehavior.DEVELOPMENT_BASED] += 0.10
                weights[VotingBehavior.CASTE_BASED] = max(0, weights[VotingBehavior.CASTE_BASED] - 0.10)
            else:
                weights[VotingBehavior.CASTE_BASED] += 0.10
                weights[VotingBehavior.DEVELOPMENT_BASED] = max(0, weights[VotingBehavior.DEVELOPMENT_BASED] - 0.10)
           
             Adjust based on sensitive booth
            if booth.get('sensitive_booth', False):
                weights[VotingBehavior.MONEY_BASED] += 0.05
                weights[VotingBehavior.CASTE_BASED] += 0.05
           
             Normalize weights
            behaviors = list(weights.keys())
            probs = list(weights.values())
            probs = [max(0, p) for p in probs]
            total = sum(probs)
            probs = [p/total for p in probs]
           
            return random.choices(behaviors, weights=probs)[0]
       
        def _generate_preferences(self, behavior: VotingBehavior,
                                 caste: str, religion: str,
                                 booth: Dict) -> List[str]:
            """
            Generate ranked preferences based on voting behavior
            """
            candidates = list(self.candidates.keys())
           
            if behavior == VotingBehavior.CASTE_BASED:
                 Same caste candidates first
                same_caste = [c for c in candidates
                             if self.candidates[c]['caste'] == caste]
                others = [c for c in candidates if c not in same_caste]
                random.shuffle(others)
                preferences = same_caste + others
               
            elif behavior == VotingBehavior.COMMUNITY_BASED:
                 Same religion candidates first
                same_religion = [c for c in candidates
                               if self.candidates[c]['religion'] == religion]
                others = [c for c in candidates if c not in same_religion]
                random.shuffle(others)
                preferences = same_religion + others
               
            elif behavior == VotingBehavior.DEVELOPMENT_BASED:
                 Educated, clean candidates first
                def development_score(c):
                    score = 0
                    if self.candidates[c]['education'] in ['Post Graduate', 'Doctorate']:
                        score += 3
                    if self.candidates[c]['criminal_records'] == 0:
                        score += 2
                    if self.candidates[c]['local_resident']:
                        score += 1
                    return score
               
                preferences = sorted(candidates,
                                   key=lambda c: development_score(c),
                                   reverse=True)
                
            elif behavior == VotingBehavior.LEADER_BASED:
                 National party candidates first
                national_candidates = [c for c in candidates
                                     if self.parties[self.candidates[c]['party_id']]['national_party']]
                regional_candidates = [c for c in candidates if c not in national_candidates]
                random.shuffle(regional_candidates)
                preferences = national_candidates + regional_candidates
               
            elif behavior == VotingBehavior.PARTY_BASED:
                 Random party preference
                parties = list(self.parties.keys())
                preferred_party = random.choice(parties)
                party_candidates = [c for c in candidates
                                  if self.candidates[c]['party_id'] == preferred_party]
                others = [c for c in candidates if c not in party_candidates]
                random.shuffle(others)
                preferences = party_candidates + others
                
            elif behavior == VotingBehavior.DYNASTY_BASED:
                 Dynasty candidates first
                dynasty_candidates = [c for c in candidates
                                    if self.candidates[c]['dynasty_legacy']]
                others = [c for c in candidates if c not in dynasty_candidates]
                random.shuffle(others)
                preferences = dynasty_candidates + others
               
            elif behavior == VotingBehavior.MONEY_BASED:
                 Rich candidates first (based on assets)
                preferences = sorted(candidates,
                                   key=lambda c: self.candidates[c]['assets'],
                                   reverse=True)
               
            else:   Random/Family Tradition
                preferences = candidates.copy()
                random.shuffle(preferences)
           
             Add NOTA at appropriate position
            if self.use_nota:
                if random.random() < 0.02:   2% chance of NOTA as first preference
                    preferences.insert(0, "NOTA")
                else:
                    preferences.append("NOTA")
           
            return preferences
       
         ==================== VOTING SIMULATION ====================
       
        def simulate_voting(self, turnout_percentage: float = 0.7,
                           evm_failure_rate: float = 0.001,
                           postal_percentage: float = 0.05):
            """
            Simulate voting process with EVM and postal ballots
            """
            print(f"\nSIMULATING VOTING PROCESS...")
            print(f"   Target Turnout: {turnout_percentage100:.1f}%")
            print(f"   EVM Failure Rate: {evm_failure_rate100:.3f}%")
            print(f"   Postal Ballots: {postal_percentage100:.1f}%")
           
            self.turnout_percentage = turnout_percentage
            
            total_ballots = 0
            postal_count = 0
           
            for booth in self.booths:
                booth_voters = [v for v in self.voter_demographics
                              if v['booth_id'] == booth['id']]
               
                if not booth_voters:
                    continue
               
                 Calculate actual turnout with some variation
                booth_turnout = turnout_percentage  random.uniform(0.9, 1.1)
                booth_turnout = min(0.95, max(0.5, booth_turnout))
               
                 Determine number of voters who actually vote
                num_voted = int(len(booth_voters)  booth_turnout)
                voted_indices = random.sample(range(len(booth_voters)), num_voted)
               
                 Calculate postal ballots
                num_postal = int(num_voted  postal_percentage  random.uniform(0.8, 1.2))
                postal_indices = random.sample(voted_indices, min(num_postal, num_voted))
               
                for idx in voted_indices:
                    voter = booth_voters[idx]
                   
                     Check if postal ballot
                    is_postal = idx in postal_indices
                   
                     Check EVM malfunction (only for non-postal votes)
                    if not is_postal and random.random() < evm_failure_rate:
                        self.evm_malfunctions += 1
                        if random.random() < 0.3:   30% chance of re-poll
                            if booth['id'] not in self.re_poll_booths:
                                self.re_poll_booths.append(booth['id'])
                        continue
                   
                     Create ballot
                    ballot = {
                        'voter_id': voter['id'],
                        'booth_id': booth['id'],
                        'preferences': voter['preferences'].copy(),
                        'current_preference': 0,
                        'weight': 1.0,
                        'postal': is_postal,
                        'timestamp': datetime.now()
                    }
                    
                    if is_postal:
                        self.postal_ballots.append(ballot)
                        postal_count += 1
                    else:
                        self.ballots.append(ballot)
                   
                    voter['voted'] = True
                    total_ballots += 1
                   
                     Update booth vote counts
                    first_pref = ballot['preferences'][0] if ballot['preferences'] else "NOTA"
                    if first_pref == "NOTA":
                        booth['nota_count'] += 1
                    else:
                        booth['evm_votes'][first_pref] = booth['evm_votes'].get(first_pref, 0) + 1
               
                booth['actual_turnout'] = num_voted / len(booth_voters) if booth_voters else 0
           
             Count NOTA first preferences
            self.nota_votes = sum(1 for b in self.ballots + self.postal_ballots
                                if b['preferences'] and b['preferences'][0] == "NOTA")
           
            print(f"\n   Voting Complete:")
            print(f"      Total ballots cast: {total_ballots}")
            print(f"      EVM ballots: {len(self.ballots)}")
            print(f"      Postal ballots: {len(self.postal_ballots)}")
            print(f"      NOTA first preferences: {self.nota_votes}")
            print(f"      EVM malfunctions: {self.evm_malfunctions}")
            print(f"      Booths needing re-poll: {len(self.re_poll_booths)}")
       
         ==================== COUNTING PROCESS ====================
       
        def calculate_quota(self, total_valid_votes: int) -> float:
            """Calculate quota based on selected method"""
            if self.quota_type == "droop":
                return math.floor(total_valid_votes / (self.total_seats + 1)) + 1
            elif self.quota_type == "hare":
                return total_valid_votes / self.total_seats
            elif self.quota_type == "imperiali":
                return total_valid_votes / (self.total_seats + 2)
            else:
                return total_valid_votes / (self.total_seats + 1)
       
        def count_booth_wise(self) -> Dict:
            """Count votes booth by booth (Indian EVM style)"""
            print(f"\nBOOTH-WISE COUNTING...")
           
            booth_results = {}
           
            for booth in self.booths:
                booth_id = booth['id']
                booth_ballots = [b for b in self.ballots if b['booth_id'] == booth_id]
                booth_postal = [b for b in self.postal_ballots if b['booth_id'] == booth_id]
               
                 Count booth-wise
                booth_counts = defaultdict(float)
                postal_counts = defaultdict(float)
               
                for ballot in booth_ballots:
                    if ballot['preferences']:
                        pref = ballot['preferences'][0]
                        if pref != "NOTA":
                            booth_counts[pref] += 1
                        else:
                            booth_counts["NOTA"] += 1
               
                for ballot in booth_postal:
                    if ballot['preferences']:
                        pref = ballot['preferences'][0]
                        if pref != "NOTA":
                            postal_counts[pref] += 1
                        else:
                            postal_counts["NOTA"] += 1
               
                 Combine EVM and postal
                total_counts = defaultdict(float)
                for cand, votes in booth_counts.items():
                    total_counts[cand] += votes
                for cand, votes in postal_counts.items():
                    total_counts[cand] += votes
               
                 Determine leading candidate
                leading = None
                if total_counts:
                    leading = max(total_counts.items(), key=lambda x: x[1])
               
                booth_results[booth_id] = {
                    'name': booth['name'],
                    'evm_votes': dict(booth_counts),
                    'postal_votes': dict(postal_counts),
                    'total_votes': dict(total_counts),
                    'total_count': len(booth_ballots) + len(booth_postal),
                    'turnout': booth['actual_turnout'],
                    'leading_candidate': leading[0] if leading else None,
                    'leading_votes': leading[1] if leading else 0,
                    'nota_count': booth['nota_count']
                }
               
                 Calculate margin
                if len(total_counts) >= 2:
                    sorted_counts = sorted(total_counts.items(), key=lambda x: -x[1])
                    booth_results[booth_id]['margin'] = sorted_counts[0][1] - sorted_counts[1][1]
               
                print(f"   Booth {booth['name']}: {booth_results[booth_id]['total_count']} votes | "
                      f"Leading: {booth_results[booth_id]['leading_candidate']}")
           
            return booth_results
       
        def run_election(self, verbose: bool = True) -> Dict:
            """
            Run the complete election process
            """
            print(f"\n{'='80}")
            print(f"ELECTION COUNTING PROCESS STARTING")
            print(f"{'='80}")
           
             Combine all ballots
            all_ballots = self.ballots + self.postal_ballots
           
            if not all_ballots:
                print("No ballots to count!")
                return {}
           
             Filter out NOTA first preferences
            active_ballots = [b for b in all_ballots
                             if b['preferences'] and b['preferences'][0] != "NOTA"]
           
            print(f"\n   Total ballots: {len(all_ballots)}")
            print(f"   NOTA first preferences: {self.nota_votes}")
            print(f"   Active ballots: {len(active_ballots)}")
           
             Booth-wise results
            booth_results = self.count_booth_wise()
           
             Initialize counting
            elected = []
            eliminated = []
            round_num = 1
            total_valid_votes = len(active_ballots)
            quota = self.calculate_quota(total_valid_votes)
           
            print(f"\nQuota needed: {quota:.3f} votes")
           
             Main counting rounds
            while len(elected) < self.total_seats and len([c for c in self.candidates.values() if c['active']]) > 0:
                print(f"\n{'─'50}")
                print(f"ROUND {round_num}")
                print(f"{'─'50}")
               
                 Count current preferences
                counts = defaultdict(float)
                candidate_ballots = defaultdict(list)
               
                for ballot in active_ballots:
                    if ballot['current_preference'] < len(ballot['preferences']):
                        pref_idx = ballot['current_preference']
                        candidate_id = ballot['preferences'][pref_idx]
                       
                        if candidate_id != "NOTA" and candidate_id in self.candidates:
                            if self.candidates[candidate_id]['active']:
                                counts[candidate_id] += ballot['weight']
                                candidate_ballots[candidate_id].append(ballot)
               
                if not counts:
                    print("   No more active candidates!")
                    break
               
                 Record round
                round_data = {
                    'round': round_num,
                    'counts': dict(counts),
                    'quota': quota,
                    'total_votes': sum(counts.values()),
                    'elected_this_round': [],
                    'eliminated_this_round': []
                }
               
                if verbose:
                    print(f"\nVote counts:")
                    for cand_id, votes in sorted(counts.items(), key=lambda x: -x[1]):
                        cand = self.candidates[cand_id]
                        status = "ELECTED" if votes >= quota else ""
                        print(f"  {cand['name']} ({cand['party_name']}): {votes:.3f} {status}")
               
                 Check for elected candidates
                newly_elected = []
                for cand_id, votes in counts.items():
                    if votes >= quota and cand_id not in elected:
                        newly_elected.append(cand_id)
                        elected.append(cand_id)
                        self.candidates[cand_id]['elected_round'] = round_num
                        self.candidates[cand_id]['total_votes'] = votes
                        round_data['elected_this_round'].append(cand_id)
                       
                         Calculate margin
                        other_votes = [v for c, v in counts.items() if c != cand_id]
                        if other_votes:
                            self.candidates[cand_id]['margin'] = votes - max(other_votes)
                       
                        print(f"\n  {self.candidates[cand_id]['name']} ELECTED! (Round {round_num})")
                        print(f"     Votes: {votes:.3f} | Margin: {self.candidates[cand_id]['margin']:.3f}")
                       
                         Redistribute surplus
                        surplus = votes - quota
                        if surplus > 0.001 and len(elected) < self.total_seats:
                            print(f"     Redistributing surplus of {surplus:.3f} votes")
                            self._redistribute_surplus(surplus, candidate_ballots[cand_id])
               
                 If no one elected, eliminate lowest candidate
                if not newly_elected and counts:
                     Find lowest candidate
                    min_votes = min(counts.values())
                    lowest_candidates = [c for c, v in counts.items() if v == min_votes]
                   
                     Tie-breaking
                    if len(lowest_candidates) > 1:
                        eliminated_cand = self._tie_break(lowest_candidates, counts)
                    else:
                        eliminated_cand = lowest_candidates[0]
                   
                     Eliminate candidate
                    self.candidates[eliminated_cand]['active'] = False
                    self.candidates[eliminated_cand]['eliminated_round'] = round_num
                    eliminated.append(eliminated_cand)
                    round_data['eliminated_this_round'].append(eliminated_cand)
                   
                    print(f"\n  {self.candidates[eliminated_cand]['name']} ELIMINATED")
                    print(f"     Votes: {min_votes:.3f}")
                   
                     Transfer votes
                    for ballot in candidate_ballots.get(eliminated_cand, []):
                        ballot['current_preference'] += 1
               
                self.rounds.append(round_data)
                round_num += 1
               
                 Check if we can fill remaining seats
                if len(elected) < self.total_seats:
                    remaining_active = [c for c in self.candidates
                                      if self.candidates[c]['active'] and c not in elected]
                    if len(remaining_active) <= (self.total_seats - len(elected)):
                        print(f"\n  Filling remaining seats from active candidates")
                        for cand_id in remaining_active:
                            elected.append(cand_id)
                            self.candidates[cand_id]['elected_round'] = round_num
                            print(f"     {self.candidates[cand_id]['name']} ELECTED (unopposed)")
                        break
           
             Prepare and return results
            return self._generate_results(elected, eliminated, booth_results)
       
        def _redistribute_surplus(self, surplus: float, ballots_to_transfer: List):
            """Redistribute surplus votes using fractional transfer"""
            if not ballots_to_transfer:
                return
           
            transfer_value = surplus / len(ballots_to_transfer)
           
            for ballot in ballots_to_transfer:
                ballot['current_preference'] += 1
                if ballot['current_preference'] < len(ballot['preferences']):
                    ballot['weight'] = transfer_value
       
        def _tie_break(self, tied_candidates: List[str],
                       current_counts: Dict[str, float]) -> str:
            """Indian-style tie-breaking"""
            print(f"\n  TIE DETECTED between: {tied_candidates}")
           
             Method 1: Check age (older candidate gets preference)
            oldest = max(tied_candidates,
                        key=lambda c: self.candidates[c]['age'])
           
             Method 2: Check criminal records (cleaner candidate)
            cleanest = min(tied_candidates,
                          key=lambda c: self.candidates[c]['criminal_records'])
           
             Method 3: Check assets (less wealthy gets preference - anti-money)
            poorest = min(tied_candidates,
                         key=lambda c: self.candidates[c]['assets'])
           
             Method 4: Random draw (lottery)
            if oldest == cleanest == poorest:
                winner = random.choice(tied_candidates)
                print(f"     Using random lottery: {self.candidates[winner]['name']}")
                return winner
            elif oldest == cleanest:
                print(f"     Winner by age and clean record: {self.candidates[oldest]['name']}")
                return oldest
            else:
                 Prefer older candidate
                print(f"     Winner by age: {self.candidates[oldest]['name']}")
                return oldest
       
        def _generate_results(self, elected: List[str],
                             eliminated: List[str],
                             booth_results: Dict) -> Dict:
            """Generate comprehensive final results"""
           
             Calculate party-wise results
            party_results = {}
            for party_id, party in self.parties.items():
                party_candidates = [c for c in elected if c in party['candidates']]
                party_votes = sum(self.candidates[c]['total_votes'] for c in party['candidates'] if c in elected)
               
                party_results[party_id] = {
                    'name': party['name'],
                    'symbol': party['symbol'],
                    'seats_won': len(party_candidates),
                    'total_votes': party_votes,
                    'candidates_elected': party_candidates,
                    'vote_share': (party_votes / len(self.ballots + self.postal_ballots)  100) if self.ballots else 0
                }
           
             Alliance results
            alliance_results = {}
            if self.enable_alliances:
                for alliance_id, alliance in self.alliances.items():
                    alliance_seats = 0
                    alliance_votes = 0
                    alliance_candidates = []
                   
                    for party_id in alliance['member_parties']:
                        if party_id in party_results:
                            alliance_seats += party_results[party_id]['seats_won']
                            alliance_votes += party_results[party_id]['total_votes']
                            alliance_candidates.extend(party_results[party_id]['candidates_elected'])
                   
                    alliance_results[alliance_id] = {
                        'name': alliance['name'],
                        'seats_won': alliance_seats,
                        'total_votes': alliance_votes,
                        'candidates_elected': alliance_candidates
                    }
           
             Demographic analysis
            demographic_breakdown = self._analyze_demographic_voting(elected)
           
             NOTA analysis
            nota_analysis = {
                'total_nota': self.nota_votes,
                'nota_percentage': (self.nota_votes / len(self.ballots + self.postal_ballots)  100) if self.ballots else 0,
                'booths_highest_nota': max(booth_results.items(),
                                          key=lambda x: x[1].get('nota_count', 0))[0] if booth_results else None
            }
           
            return {
                'election_name': self.election_name,
                'election_level': self.election_level,
                'state': self.state,
                'constituency': self.constituency_name,
                'date': datetime.now().isoformat(),
                'total_voters': self.total_voters,
                'turnout': self.turnout_percentage,
                'total_ballots': len(self.ballots) + len(self.postal_ballots),
                'valid_votes': len(self.ballots) + len(self.postal_ballots) - self.nota_votes,
                'nota_analysis': nota_analysis,
                'quota_type': self.quota_type,
                'quota_used': self.calculate_quota(len(self.ballots) + len(self.postal_ballots) - self.nota_votes),
                'rounds': len(self.rounds),
                'elected_candidates': [
                    {
                        'id': c,
                        'name': self.candidates[c]['name'],
                        'party': self.candidates[c]['party_name'],
                        'party_id': self.candidates[c]['party_id'],
                        'votes': self.candidates[c]['total_votes'],
                        'margin': self.candidates[c]['margin'],
                        'elected_round': self.candidates[c]['elected_round']
                    } for c in elected
                ],
                'eliminated_candidates': [
                    {
                        'id': c,
                        'name': self.candidates[c]['name'],
                        'party': self.candidates[c]['party_name'],
                        'eliminated_round': self.candidates[c]['eliminated_round']
                    } for c in eliminated
                ],
                'party_results': party_results,
                'alliance_results': alliance_results,
                'booth_results': booth_results,
                'demographic_breakdown': demographic_breakdown,
                'technical_issues': {
                    'evm_malfunctions': self.evm_malfunctions,
                    're_poll_booths': self.re_poll_booths
                }
            }
       
        def _analyze_demographic_voting(self, elected: List[str]) -> Dict:
            """Analyze voting patterns by demographic groups"""
           
            demographic = {
                'caste_representation': defaultdict(int),
                'religion_representation': defaultdict(int),
                'age_distribution': [],
                'education_levels': defaultdict(int),
                'criminal_record_candidates': 0,
                'dynasty_candidates': 0,
                'incumbents_reelected': 0,
                'average_assets': 0
            }
           
            total_assets = 0
           
            for cand_id in elected:
                cand = self.candidates[cand_id]
                demographic['caste_representation'][cand['caste']] += 1
                demographic['religion_representation'][cand['religion']] += 1
                demographic['age_distribution'].append(cand['age'])
                demographic['education_levels'][cand['education']] += 1
                if cand['criminal_records'] > 0:
                    demographic['criminal_record_candidates'] += 1
                if cand['dynasty_legacy']:
                    demographic['dynasty_candidates'] += 1
                if cand['incumbency']:
                    demographic['incumbents_reelected'] += 1
                total_assets += cand['assets']
           
            if elected:
                demographic['average_assets'] = total_assets / len(elected)
                demographic['average_age'] = sum(demographic['age_distribution']) / len(elected)
            else:
                demographic['average_assets'] = 0
                demographic['average_age'] = 0
           
             Convert defaultdicts to dict
            demographic['caste_representation'] = dict(demographic['caste_representation'])
            demographic['religion_representation'] = dict(demographic['religion_representation'])
            demographic['education_levels'] = dict(demographic['education_levels'])
           
            return demographic
       
        def print_results(self, results: Dict):
            """Print comprehensive election results"""
           
            print(f"\n{'='80}")
            print(f"FINAL ELECTION RESULTS: {results['election_name']}")
            print(f"{'='80}")
           
             Election summary
            print(f"\nELECTION SUMMARY:")
            print(f"   Level: {results['election_level']}")
            print(f"   State: {results['state']}")
            print(f"   Constituency: {results['constituency']}")
            print(f"   Date: {results['date'][:10]}")
            print(f"   Total Voters: {results['total_voters']:,}")
            print(f"   Turnout: {results['turnout']100:.1f}%")
            print(f"   Total Ballots: {results['total_ballots']:,}")
            print(f"   Valid Votes: {results['valid_votes']:,}")
           
             NOTA
            print(f"\nNOTA ANALYSIS:")
            print(f"   Total NOTA: {results['nota_analysis']['total_nota']}")
            print(f"   NOTA Percentage: {results['nota_analysis']['nota_percentage']:.2f}%")
            if results['nota_analysis']['booths_highest_nota']:
                booth_id = results['nota_analysis']['booths_highest_nota']
                print(f"   Highest NOTA Booth: {results['booth_results'][booth_id]['name']}")
           
             Elected candidates
            print(f"\nELECTED CANDIDATES ({len(results['elected_candidates'])} seats):")
            for i, cand in enumerate(results['elected_candidates'], 1):
                print(f"   {i}. {cand['name']} ({cand['party']})")
                print(f"      Votes: {cand['votes']:.3f} | Margin: {cand['margin']:.3f} | Round: {cand['elected_round']}")
           
             Party results
            print(f"\nPARTY-WISE RESULTS:")
            for party_id, party in sorted(results['party_results'].items(),
                                         key=lambda x: -x[1]['seats_won']):
                if party['seats_won'] > 0:
                    print(f"   {party['name']} ({party['symbol']}): {party['seats_won']} seats | "
                          f"{party['vote_share']:.1f}% vote share")
           
             Alliance results
            if results['alliance_results']:
                print(f"\nALLIANCE-WISE RESULTS:")
                for alliance_id, alliance in sorted(results['alliance_results'].items(),
                                                  key=lambda x: -x[1]['seats_won']):
                    if alliance['seats_won'] > 0:
                        print(f"   {alliance['name']}: {alliance['seats_won']} seats")
           
             Demographic breakdown
            print(f"\nDEMOGRAPHIC BREAKDOWN:")
            demo = results['demographic_breakdown']
            print(f"   Average Age: {demo['average_age']:.1f} years")
            print(f"   Average Assets: ₹{demo['average_assets']:.2f} crores")
            print(f"   Criminal Record Holders: {demo['criminal_record_candidates']}")
            print(f"   Dynasty Candidates: {demo['dynasty_candidates']}")
            print(f"   Incumbents Re-elected: {demo['incumbents_reelected']}")
           
            print(f"\n   Caste Representation:")
            for caste, count in demo['caste_representation'].items():
                print(f"      {caste}: {count}")
           
            print(f"\n   Education Levels:")
            for edu, count in demo['education_levels'].items():
                print(f"      {edu}: {count}")
           
             Technical issues
            print(f"\nTECHNICAL ISSUES:")
            print(f"   EVM Malfunctions: {results['technical_issues']['evm_malfunctions']}")
            print(f"   Re-poll Booths: {len(results['technical_issues']['re_poll_booths'])}")
            for booth_id in results['technical_issues']['re_poll_booths']:
                if booth_id in results['booth_results']:
                    print(f"      - {results['booth_results'][booth_id]['name']}")
           
            print(f"\n{'='80}")
       
        def export_results(self, results: Dict, filename: str = "election_results.json"):
            """Export results to JSON file"""
            try:
                 Convert datetime objects to strings
                if 'date' in results and isinstance(results['date'], datetime):
                    results['date'] = results['date'].isoformat()
               
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(results, f, indent=2, ensure_ascii=False)
                print(f"\nResults exported to {filename}")
            except Exception as e:
                print(f"\nError exporting results: {e}")

     ==================== EXAMPLE USAGE ====================

    def run_indian_election_example():
        """Run a complete Indian election example"""
       
        print("\n" + "="80)
        print("INDIAN GENERAL ELECTION 2024 - SIMULATION")
        print("="80)
       
         Create voting system for Lok Sabha election
        election = IndianVotingSystem(
            election_name="Indian General Election 2024",
            election_level=ElectionLevel.LOK_SABHA,
            state="Uttar Pradesh",
            constituency_name="Lucknow",
            total_seats=1,
            quota_type="droop",
            use_nota=True,
            enable_alliances=True,
            demographic_analysis=True
        )
       
         Add political parties
        election.add_party("BJP", "Bharatiya Janata Party", "Lotus",
                          "Hindu Nationalism", 1980, national_party=True)
        election.add_party("INC", "Indian National Congress", "Hand",
                          "Secular Liberalism", 1885, national_party=True)
        election.add_party("SP", "Samajwadi Party", "Cycle",
                          "Socialism", 1992, national_party=False)
        election.add_party("BSP", "Bahujan Samaj Party", "Elephant",
                          "Social Justice", 1984, national_party=False)
        election.add_party("AAP", "Aam Aadmi Party", "Broom",
                          "Anti-Corruption", 2012, national_party=False)
       
         Create alliances
        election.create_alliance("NDA", "National Democratic Alliance",
                                AllianceType.PRE_POLL, ["BJP"])
        election.create_alliance("INDIA", "Indian National Developmental Inclusive Alliance",
                                AllianceType.PRE_POLL, ["INC", "SP"])
       
         Add candidates
        election.add_candidate(
            candidate_id="C1",
            name="Rajesh Kumar Singh",
            party_id="BJP",
            constituency="Lucknow",
            age=55,
            education="Post Graduate",
            criminal_records=0,
            assets=15.5,
            liabilities=2.3,
            caste=CasteCategory.GENERAL,
            religion=Religion.HINDU,
            local_resident=True,
            dynasty_legacy=False,
            incumbency=True
        )
       
        election.add_candidate(
            candidate_id="C2",
            name="Priya Sharma",
            party_id="INC",
            constituency="Lucknow",
            age=48,
            education="Graduate",
            criminal_records=0,
            assets=8.2,
            liabilities=1.1,
            caste=CasteCategory.GENERAL,
            religion=Religion.HINDU,
            local_resident=True,
            dynasty_legacy=True,
            incumbency=False
        )
       
        election.add_candidate(
            candidate_id="C3",
            name="Mohammad Ali",
            party_id="SP",
            constituency="Lucknow",
            age=52,
            education="Graduate",
            criminal_records=2,
            assets=12.8,
            liabilities=3.4,
            caste=CasteCategory.OBC,
            religion=Religion.MUSLIM,
            local_resident=True,
            dynasty_legacy=False,
            incumbency=False
        )
       
        election.add_candidate(
            candidate_id="C4",
            name="Kanti Prasad",
            party_id="BSP",
            constituency="Lucknow",
            age=60,
            education="High School",
            criminal_records=1,
            assets=5.6,
            liabilities=0.8,
            caste=CasteCategory.SC,
            religion=Religion.BUDDHIST,
            local_resident=True,
            dynasty_legacy=False,
            incumbency=False
        )
       
        election.add_candidate(
            candidate_id="C5",
            name="Arvind Mishra",
            party_id="AAP",
            constituency="Lucknow",
            age=45,
            education="Doctorate",
            criminal_records=0,
            assets=3.2,
            liabilities=0.5,
            caste=CasteCategory.GENERAL,
            religion=Religion.HINDU,
            local_resident=False,
            dynasty_legacy=False,
            incumbency=False
        )
       
         Add polling booths with demographics
        election.add_booth(
            booth_id="B001",
            name="Gomti Nagar",
            region=Region.NORTH,
            urban_rural=UrbanRural.URBAN,
            total_voters=5000,
            demographics={
                CasteCategory.GENERAL: 0.35,
                CasteCategory.OBC: 0.30,
                CasteCategory.SC: 0.20,
                CasteCategory.ST: 0.05,
                CasteCategory.MINORITY: 0.10
            },
            religious_demographics={
                Religion.HINDU: 0.75,
                Religion.MUSLIM: 0.15,
                Religion.SIKH: 0.05,
                Religion.CHRISTIAN: 0.03,
                Religion.OTHER: 0.02
            },
            language=Language.HINDI,
            historical_turnout=0.68,
            sensitive_booth=False
        )
       
        election.add_booth(
            booth_id="B002",
            name="Chowk",
            region=Region.NORTH,
            urban_rural=UrbanRural.URBAN,
            total_voters=4500,
            demographics={
                CasteCategory.GENERAL: 0.25,
                CasteCategory.OBC: 0.35,
                CasteCategory.SC: 0.20,
                CasteCategory.ST: 0.05,
                CasteCategory.MINORITY: 0.15
            },
            religious_demographics={
                Religion.HINDU: 0.65,
                Religion.MUSLIM: 0.25,
                Religion.SIKH: 0.05,
                Religion.CHRISTIAN: 0.03,
                Religion.OTHER: 0.02
            },
            language=Language.HINDI,
            historical_turnout=0.72,
            sensitive_booth=True
        )
       
        election.add_booth(
            booth_id="B003",
            name="Aliganj",
            region=Region.NORTH,
            urban_rural=UrbanRural.SEMI_URBAN,
            total_voters=4000,
            demographics={
                CasteCategory.GENERAL: 0.30,
                CasteCategory.OBC: 0.35,
                CasteCategory.SC: 0.20,
                CasteCategory.ST: 0.05,
                CasteCategory.MINORITY: 0.10
            },
            religious_demographics={
                Religion.HINDU: 0.80,
                Religion.MUSLIM: 0.12,
                Religion.SIKH: 0.03,
                Religion.CHRISTIAN: 0.03,
                Religion.OTHER: 0.02
            },
            language=Language.HINDI,
            historical_turnout=0.70,
            sensitive_booth=False
        )
       
        election.add_booth(
            booth_id="B004",
            name="Kakori",
            region=Region.NORTH,
            urban_rural=UrbanRural.RURAL,
            total_voters=3500,
            demographics={
                CasteCategory.GENERAL: 0.20,
                CasteCategory.OBC: 0.40,
                CasteCategory.SC: 0.25,
                CasteCategory.ST: 0.05,
                CasteCategory.MINORITY: 0.10
            },
            religious_demographics={
                Religion.HINDU: 0.70,
                Religion.MUSLIM: 0.20,
                Religion.SIKH: 0.05,
                Religion.CHRISTIAN: 0.03,
                Religion.OTHER: 0.02
            },
            language=Language.HINDI,
            historical_turnout=0.75,
            sensitive_booth=True
        )
       
         Generate voters
        election.generate_voters(num_voters=10000)
       
         Simulate voting
        election.simulate_voting(
            turnout_percentage=0.72,
            evm_failure_rate=0.002,
            postal_percentage=0.06
        )
       
         Run election
        results = election.run_election(verbose=True)
       
         Print results
        election.print_results(results)
       
         Export results
        election.export_results(results, "indian_election_2024_results.json")
       
        return results

     ==================== MAIN EXECUTION ====================

    if __name__ == "__main__":
         Set random seed for reproducibility
        random.seed(42)
       
         Run the example
        results = run_indian_election_example()
       
        print(f"\nElection simulation completed successfully!")
    ```

     Key Features of This Indian Voting System:

     1. Indian Electoral Hierarchy
    - Supports multiple election levels (Panchayat to Lok Sabha)
    - State and constituency-level tracking
    - Seat-based quota system

     2. Demographic Modeling
    - Caste categories (General, OBC, SC, ST, Minority)
    - Religious demographics
    - Urban/Rural classification
    - Regional voting patterns
    - Language preferences

     3. Political Realities
    - Party system with national/state parties
    - Pre-poll and post-poll alliances
    - Seat sharing agreements
    - Dynasty politics tracking
    - Criminal background tracking
    - Asset/liability declarations

     4. Voter Behavior
    - 9 different voting behavior patterns
    - Caste-based voting
    - Community-based voting
    - Development-focused voting
    - Swing voter analysis
    - Family tradition voting

     5. Election Machinery
    - EVM and postal ballot simulation
    - Booth-level counting
    - NOTA (None of The Above) handling
    - Re-poll scenarios
    - EVM malfunction simulation

     6. Advanced Counting
    - Multi-round preferential counting
    - Surplus redistribution
    - Tie-breaking mechanisms
    - Quota calculations (Droop/Hare/Imperiali)
    - Booth-wise results

     7. Comprehensive Analysis
    - Party-wise results
    - Alliance performance
    - Demographic breakdown
    - Criminal record analysis
    - Dynasty candidate tracking
    - Education levels of winners

     8. Realistic Outputs
    - Detailed election summaries
    - JSON export capability
    - Margin calculations
    - Turnout analysis
    - Technical issue reporting
     
  • মতামত দিন
  • বিষয়বস্তু*:
  • albert banerjee | ১৪ মার্চ ২০২৬ ১১:১২747010
  • I make the model —The Indian Advanced Preferential Voting System — because I wanted to build something myself, from the ground up, in Python, that could really show how India’s extremely complicated and diverse elections actually work when we go beyond the simple “most votes wins” system we currently use.I created it because Indian elections are not just about who gets the highest number of votes in one seat. They are shaped by many deep layers:
    • enormous social diversity (caste, religion, language, region, city vs village)
    • pre-election and post-election alliances that keep rearranging vote groups
    • swing voters, NOTA option, EVM technical problems, postal votes
    • multi-stage elections from the village panchayat all the way to Parliament
    • real human voting behaviour that changes depending on the place (caste loyalty 30–40% in rural Uttar Pradesh/Bihar, development and jobs mattering 20–30% more in urban Gujarat/Maharashtra, money influences more strongly in some polling booths, etc.)
    The usual vote percentage + “winner takes all” picture hides all this complexity. So I built one simulation engine that tries to bring all these layers together into something you can actually run and play with. Core ideas behind the model I created
    1. Voters are not the same blank pieces of paper
      Every simulated voter has a personal profile: caste group, religion, main language, city/village type, bigger region → these things change how likely they are to rank candidates in a certain order.
    2. How preferences are created is weighted and realistic (not completely random)
      Default national behaviour weights I chose (you can change them for different states):
      • Caste / community loyalty → ~28–35%
      • Loyalty to party / ideology / election symbol → ~12–18%
      • Candidate’s personality / leader’s charisma → ~10–15%
      • Development / governance performance → ~12–25% (much stronger in cities)
      • Local issues (farmer laws, language rights, water, jobs) → ~8–15%
      • Alliance chemistry (friendly parties rise in ranking) → changes dynamically
      • Anti-incumbency / tiredness of family rule / penalty for criminal cases → small but present
      • Influence of money / muscle power → 2–8% (higher in “sensitive” booths)
    3. Ranked ballots + modern counting rules
      Instead of putting one cross, voters rank as many candidates as they like.
      I included:
      • Droop quota (most widely used for stability in multi-seat races)
      • Surplus transfer (when someone gets more than needed, the extra votes move on fractionally)
      • Elimination of the lowest candidate one by one
      • NOTA treated as a real option (affects the quota but can never win)
      • Tie-breaker rules: older age first → fewer criminal cases → lower declared assets → random draw
    4. Full Indian election levels in one engine
      The same code can simulate:
      • Single village ward or panchayat seat
      • Multi-seat municipal corporation
      • State assembly (Vidhan Sabha) single seat
      • Lok Sabha single seat
      • Even a simplified version of Rajya Sabha-style preference collection across states
    5. Real messy Indian election machinery
      • Different turnout in different booths
      • EVM failure rate (can cause re-polling)
      • Percentage of postal / home votes
      • Flags for historically sensitive/high-risk booths
    That is the reason I made the model:
    To turn the very Indian mix of caste + alliances + region + money + EVM + NOTA into something you can run on a computer, break apart, change one thing, and actually understand — one simulation at a time.
     
  • মতামত দিন
  • বিষয়বস্তু*:
  • কি, কেন, ইত্যাদি
  • বাজার অর্থনীতির ধরাবাঁধা খাদ্য-খাদক সম্পর্কের বাইরে বেরিয়ে এসে এমন এক আস্তানা বানাব আমরা, যেখানে ক্রমশ: মুছে যাবে লেখক ও পাঠকের বিস্তীর্ণ ব্যবধান। পাঠকই লেখক হবে, মিডিয়ার জগতে থাকবেনা কোন ব্যকরণশিক্ষক, ক্লাসরুমে থাকবেনা মিডিয়ার মাস্টারমশাইয়ের জন্য কোন বিশেষ প্ল্যাটফর্ম। এসব আদৌ হবে কিনা, গুরুচণ্ডালি টিকবে কিনা, সে পরের কথা, কিন্তু দু পা ফেলে দেখতে দোষ কী? ... আরও ...
  • আমাদের কথা
  • আপনি কি কম্পিউটার স্যাভি? সারাদিন মেশিনের সামনে বসে থেকে আপনার ঘাড়ে পিঠে কি স্পন্ডেলাইটিস আর চোখে পুরু অ্যান্টিগ্লেয়ার হাইপাওয়ার চশমা? এন্টার মেরে মেরে ডান হাতের কড়ি আঙুলে কি কড়া পড়ে গেছে? আপনি কি অন্তর্জালের গোলকধাঁধায় পথ হারাইয়াছেন? সাইট থেকে সাইটান্তরে বাঁদরলাফ দিয়ে দিয়ে আপনি কি ক্লান্ত? বিরাট অঙ্কের টেলিফোন বিল কি জীবন থেকে সব সুখ কেড়ে নিচ্ছে? আপনার দুশ্‌চিন্তার দিন শেষ হল। ... আরও ...
  • বুলবুলভাজা
  • এ হল ক্ষমতাহীনের মিডিয়া। গাঁয়ে মানেনা আপনি মোড়ল যখন নিজের ঢাক নিজে পেটায়, তখন তাকেই বলে হরিদাস পালের বুলবুলভাজা। পড়তে থাকুন রোজরোজ। দু-পয়সা দিতে পারেন আপনিও, কারণ ক্ষমতাহীন মানেই অক্ষম নয়। বুলবুলভাজায় বাছাই করা সম্পাদিত লেখা প্রকাশিত হয়। এখানে লেখা দিতে হলে লেখাটি ইমেইল করুন, বা, গুরুচন্ডা৯ ব্লগ (হরিদাস পাল) বা অন্য কোথাও লেখা থাকলে সেই ওয়েব ঠিকানা পাঠান (ইমেইল ঠিকানা পাতার নীচে আছে), অনুমোদিত এবং সম্পাদিত হলে লেখা এখানে প্রকাশিত হবে। ... আরও ...
  • হরিদাস পালেরা
  • এটি একটি খোলা পাতা, যাকে আমরা ব্লগ বলে থাকি। গুরুচন্ডালির সম্পাদকমন্ডলীর হস্তক্ষেপ ছাড়াই, স্বীকৃত ব্যবহারকারীরা এখানে নিজের লেখা লিখতে পারেন। সেটি গুরুচন্ডালি সাইটে দেখা যাবে। খুলে ফেলুন আপনার নিজের বাংলা ব্লগ, হয়ে উঠুন একমেবাদ্বিতীয়ম হরিদাস পাল, এ সুযোগ পাবেন না আর, দেখে যান নিজের চোখে...... আরও ...
  • টইপত্তর
  • নতুন কোনো বই পড়ছেন? সদ্য দেখা কোনো সিনেমা নিয়ে আলোচনার জায়গা খুঁজছেন? নতুন কোনো অ্যালবাম কানে লেগে আছে এখনও? সবাইকে জানান। এখনই। ভালো লাগলে হাত খুলে প্রশংসা করুন। খারাপ লাগলে চুটিয়ে গাল দিন। জ্ঞানের কথা বলার হলে গুরুগম্ভীর প্রবন্ধ ফাঁদুন। হাসুন কাঁদুন তক্কো করুন। স্রেফ এই কারণেই এই সাইটে আছে আমাদের বিভাগ টইপত্তর। ... আরও ...
  • ভাটিয়া৯
  • যে যা খুশি লিখবেন৷ লিখবেন এবং পোস্ট করবেন৷ তৎক্ষণাৎ তা উঠে যাবে এই পাতায়৷ এখানে এডিটিং এর রক্তচক্ষু নেই, সেন্সরশিপের ঝামেলা নেই৷ এখানে কোনো ভান নেই, সাজিয়ে গুছিয়ে লেখা তৈরি করার কোনো ঝকমারি নেই৷ সাজানো বাগান নয়, আসুন তৈরি করি ফুল ফল ও বুনো আগাছায় ভরে থাকা এক নিজস্ব চারণভূমি৷ আসুন, গড়ে তুলি এক আড়ালহীন কমিউনিটি ... আরও ...
গুরুচণ্ডা৯-র সম্পাদিত বিভাগের যে কোনো লেখা অথবা লেখার অংশবিশেষ অন্যত্র প্রকাশ করার আগে গুরুচণ্ডা৯-র লিখিত অনুমতি নেওয়া আবশ্যক। অসম্পাদিত বিভাগের লেখা প্রকাশের সময় গুরুতে প্রকাশের উল্লেখ আমরা পারস্পরিক সৌজন্যের প্রকাশ হিসেবে অনুরোধ করি। যোগাযোগ করুন, লেখা পাঠান এই ঠিকানায় : guruchandali@gmail.com ।


মে ১৩, ২০১৪ থেকে সাইটটি বার পঠিত
পড়েই ক্ষান্ত দেবেন না। চটপট মতামত দিন