python'da gerekli kütüphaneleri kullanarak şehirlerin önemli verilerini analiz edip city_rank ve city_total_score (city_total_score 0 ve 5 arasında) verisini oluşturan python scripti yaz bu veriler eklenmiş bir şekilde appendCity.json dosyasını oluştur. en iyi python kütüphanelerini kullanarak gelişmiş bir şekilde yap. Sadece scores verilerini kullanmadan BIAS atayıp hesaplama yap. 

maxiumum avg_cost değerini ve gerekli değerleri veri setinde hesaplasın manuel girilmesin. default değerleri de hesaplayıp eklesin. önce veri setini analiz etsin sonra bu kod tam tutarlı city_rank ve city_total_score değerlerini hesaplamıyor inceleyip düzenle.

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
import json
from colorama import Fore, Style, init
import logging
from datetime import datetime

# Logging yapılandırması
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename=f'city_analysis_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'
)

class CityAnalyzer:
    def __init__(self):
        self.scaler = MinMaxScaler(feature_range=(0, 5))
        
        # Önemli faktörler için ağırlıklar (BIAS)
        self.weights = {
            'safety_weight': 0.20,
            'cost_weight': 0.15,
            'quality_weight': 0.15,
            'infrastructure_weight': 0.15,
            'social_weight': 0.15,
            'economy_weight': 0.20
        }
        
        # Varsayılan değerler
        self.default_values = {
            'safety': 2.5,
            'cost_of_living': 1000,
            'quality_of_life': 2.5,
            'internet_speed': 8,
            'healthcare': 2.5,
            'air_quality': 40
        }

    def calculate_safety_score(self, city_data):
        safety_score = city_data.get('scores', {}).get('safety', self.default_values['safety'])
        traffic_safety = city_data.get('scores', {}).get('traffic_safety', self.default_values['safety'])
        female_friendly = city_data.get('scores', {}).get('female_friendly', self.default_values['safety'])
        
        return np.mean([
            safety_score if safety_score is not None else self.default_values['safety'],
            traffic_safety if traffic_safety is not None else self.default_values['safety'],
            female_friendly if female_friendly is not None else self.default_values['safety']
        ])

    def calculate_cost_score(self, city_data):
        nomad_cost = city_data.get('costs', {}).get('nomad_cost', 3000)
        expat_cost = city_data.get('costs', {}).get('expat_cost', 2000)
        
        # Maliyet puanını tersine çeviriyoruz (düşük maliyet = yüksek puan)
        costs = [nomad_cost if nomad_cost is not None else 3000,
                expat_cost if expat_cost is not None else 2000]
        avg_cost = np.mean(costs)
        return 5 * (1 - (avg_cost / 5000))  # 5000$ maksimum referans değeri

    def calculate_quality_score(self, city_data):
        quality_of_life = city_data.get('scores', {}).get('quality_of_life', self.default_values['quality_of_life'])
        healthcare = city_data.get('scores', {}).get('healthcare', self.default_values['healthcare'])
        air_quality = 5 - (city_data.get('guides', {}).get('air_quality_avg', 50) / 20)  # Düşük değer daha iyi
        
        return np.mean([
            quality_of_life if quality_of_life is not None else self.default_values['quality_of_life'],
            healthcare if healthcare is not None else self.default_values['healthcare'],
            air_quality if air_quality is not None else 2.5
        ])

    def calculate_infrastructure_score(self, city_data):
        wifi = city_data.get('scores', {}).get('wifi', self.default_values['internet_speed'])
        walking = city_data.get('scores', {}).get('walking_available', 2.5)
        
        return np.mean([
            wifi if wifi is not None else self.default_values['internet_speed'],
            walking if walking is not None else 2.5
        ])

    def calculate_social_score(self, city_data):
        lack_of_racism = city_data.get('scores', {}).get('lack_of_racism', 2.5)
        lgbtq_friendly = city_data.get('scores', {}).get('lgbtq_friendly', 2.5)
        english_speaking = city_data.get('scores', {}).get('english_speaking', 2.5)
        
        return np.mean([
            lack_of_racism if lack_of_racism is not None else 2.5,
            lgbtq_friendly if lgbtq_friendly is not None else 2.5,
            english_speaking if english_speaking is not None else 2.5
        ])

    def calculate_economy_score(self, city_data):
        startup_score = city_data.get('scores', {}).get('startup_score', 2.5)
        gdp_per_capita = city_data.get('guides', {}).get('gdp_per_capita', 30000)
        
        # GDP puanı (maksimum 100,000$ referans alınarak)
        gdp_score = min(5, (gdp_per_capita / 100000) * 5) if gdp_per_capita is not None else 2.5
        
        return np.mean([
            startup_score if startup_score is not None else 2.5,
            gdp_score
        ])

    def calculate_total_score(self, city_data):
        safety_score = self.calculate_safety_score(city_data)
        cost_score = self.calculate_cost_score(city_data)
        quality_score = self.calculate_quality_score(city_data)
        infrastructure_score = self.calculate_infrastructure_score(city_data)
        social_score = self.calculate_social_score(city_data)
        economy_score = self.calculate_economy_score(city_data)
        
        total_score = (
            safety_score * self.weights['safety_weight'] +
            cost_score * self.weights['cost_weight'] +
            quality_score * self.weights['quality_weight'] +
            infrastructure_score * self.weights['infrastructure_weight'] +
            social_score * self.weights['social_weight'] +
            economy_score * self.weights['economy_weight']
        )
        
        return round(total_score, 2)

    def analyze_cities(self, cities_data):
        analyzed_cities = []
        
        for city in cities_data:
            try:
                city_name = city['general']['name']
                total_score = self.calculate_total_score(city)
                
                analyzed_city = {
                    **city,
                    'city_total_score': total_score,
                    'analysis_details': {
                        'safety_score': self.calculate_safety_score(city),
                        'cost_score': self.calculate_cost_score(city),
                        'quality_score': self.calculate_quality_score(city),
                        'infrastructure_score': self.calculate_infrastructure_score(city),
                        'social_score': self.calculate_social_score(city),
                        'economy_score': self.calculate_economy_score(city)
                    }
                }
                analyzed_cities.append(analyzed_city)
                logging.info(f"Successfully analyzed {city_name} with score {total_score}")
                
            except Exception as e:
                logging.error(f"Error analyzing city {city.get('general', {}).get('name', 'Unknown')}: {str(e)}")
        
        # Şehirleri toplam puana göre sıralama
        analyzed_cities.sort(key=lambda x: x['city_total_score'], reverse=True)
        
        # Sıralama ekle
        for rank, city in enumerate(analyzed_cities, 1):
            city['city_rank'] = rank
        
        return analyzed_cities

def main():
    init(autoreset=True)  # Colorama başlatma
    
    try:
        # Veriyi oku
        with open('data/23.10.2024/demo_cities_updated.json', 'r', encoding='utf-8') as file:
            cities_data = json.load(file)
        
        # Analiz yap
        analyzer = CityAnalyzer()
        analyzed_cities = analyzer.analyze_cities(cities_data)
        
        # Sonuçları kaydet
        with open('appendCityClaude.json', 'w', encoding='utf-8') as file:
            json.dump(analyzed_cities, file, indent=2, ensure_ascii=False)
        
        print(f"{Fore.GREEN}Analysis completed successfully!")
        print(f"{Fore.CYAN}Top 5 Cities:")
        for city in analyzed_cities[:5]:
            print(f"{Fore.YELLOW}Rank {city['city_rank']}: {city['general']['name']} - Score: {city['city_total_score']}")
            
    except Exception as e:
        print(f"{Fore.RED}An error occurred: {str(e)}")
        logging.error(f"Main execution error: {str(e)}")

if __name__ == "__main__":
    main()

örnek veri seti

[
  {
    "url": "https://nomads.com/minot",
    "short_slug": "minot",
    "general": {
      "name": "Minot, ND",
      "long_slug": "minot-nd-united-states",
      "continent": "North America",
      "country": "United States",
      "latitude": 48.2325,
      "longitude": -101.2963,
      "similar_cities": [
        {
          "name": "Las Vegas, NV",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "las-vegas",
          "distance_time": 120,
          "vehicle_type": "plane"
        },
        {
          "name": "San Antonio, TX",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "san-antonio",
          "distance_time": 180,
          "vehicle_type": "plane"
        },
        {
          "name": "Los Angeles, CA",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "los-angeles",
          "distance_time": 180,
          "vehicle_type": "plane"
        },
        {
          "name": "New York City, NY",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "new-york-city",
          "distance_time": 180,
          "vehicle_type": "plane"
        },
        {
          "name": "Orlando, FL",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "orlando",
          "distance_time": 240,
          "vehicle_type": "plane"
        },
        {
          "name": "Miami, FL",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "miami",
          "distance_time": 240,
          "vehicle_type": "plane"
        },
        {
          "name": "Cancun",
          "country": "Mexico",
          "country_slug": "mexico",
          "short_slug": "cancun",
          "distance_time": 240,
          "vehicle_type": "plane"
        },
        {
          "name": "Bogota",
          "country": "Colombia",
          "country_slug": "colombia",
          "short_slug": "bogota",
          "distance_time": 420,
          "vehicle_type": "plane"
        },
        {
          "name": "Cairo",
          "country": "Egypt",
          "country_slug": "egypt",
          "short_slug": "cairo",
          "distance_time": 780,
          "vehicle_type": "plane"
        },
        {
          "name": "Dubai",
          "country": "United Arab Emirates",
          "country_slug": "united-arab-emirates",
          "short_slug": "dubai",
          "distance_time": 900,
          "vehicle_type": "plane"
        }
      ],
      "near_cities": [
        {
          "name": "Bismarck, ND",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "bismarck",
          "distance_time": 21,
          "vehicle_type": "plane"
        },
        {
          "name": "Regina",
          "country": "Canada",
          "country_slug": "canada",
          "short_slug": "regina",
          "distance_time": 28,
          "vehicle_type": "plane"
        },
        {
          "name": "Grand Forks, ND",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "grand-forks",
          "distance_time": 28,
          "vehicle_type": "plane"
        },
        {
          "name": "Winnipeg",
          "country": "Canada",
          "country_slug": "canada",
          "short_slug": "winnipeg",
          "distance_time": 28,
          "vehicle_type": "plane"
        },
        {
          "name": "Fargo, ND",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "fargo",
          "distance_time": 30,
          "vehicle_type": "plane"
        },
        {
          "name": "Rapid City, SD",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "rapid-city",
          "distance_time": 39,
          "vehicle_type": "plane"
        },
        {
          "name": "Saskatoon",
          "country": "Canada",
          "country_slug": "canada",
          "short_slug": "saskatoon",
          "distance_time": 46,
          "vehicle_type": "plane"
        },
        {
          "name": "Billings, MT",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "billings",
          "distance_time": 50,
          "vehicle_type": "plane"
        },
        {
          "name": "St. Cloud, MN",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "st-cloud",
          "distance_time": 53,
          "vehicle_type": "plane"
        },
        {
          "name": "Minneapolis, MN",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "minneapolis",
          "distance_time": 57,
          "vehicle_type": "plane"
        },
        {
          "name": "Sioux Falls, SD",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "sioux-falls",
          "distance_time": 57,
          "vehicle_type": "plane"
        },
        {
          "name": "Casper, WY",
          "country": "United States",
          "country_slug": "united-states",
          "short_slug": "casper",
          "distance_time": 57,
          "vehicle_type": "plane"
        }
      ],
      "pros": [
        "Pretty safe",
        "Fast internet",
        "Perfect humidity now",
        "Good air quality on average",
        "Spacious and not crowded",
        "Very easy to do business",
        "High quality of education",
        "Great hospitals",
        "Roads are very safe",
        "Great freedom of speech",
        "Democratic",
        "Everyone speaks English",
        "Very safe for women",
        "Family friendly",
        "Very friendly to LGBTQ+",
        "Not many people smoke tobacco",
        "(Medical) marijuana MAY be legal, unenforced or decriminalized (always double check this)"
      ],
      "cons": [
        "Very expensive",
        "Not much to do",
        "Gets very cold in the winter",
        "Difficult to make friends",
        "High alcohol consumption"
      ]
    },
    "scores": {
      "nightlife": 3.0,
      "working_places": null,
      "family_friendly": 3.5659197347,
      "safety": 4,
      "quality_of_life": 3.4022399375,
      "education": 4.3888888889,
      "wifi": 4.0,
      "fun": 3.0,
      "walking_available": 5.0,
      "healthcare": 4.3790746144,
      "lack_of_racism": 4.5,
      "english_speaking": 5.0,
      "traffic_safety": 3.0,
      "foreigners_friendly": null,
      "female_friendly": 4.0,
      "lgbtq_friendly": 5.0,
      "startup_score": 2.9846505973
    },
    "guides": {
      "average_trip_length": null,
      "internet_speed_avg": 35.0,
      "air_quality_avg": 18,
      "power": {
        "plug_types": ["American-type A-plug"],
        "voltage": "115V",
        "frequency": "60Hz"
      },
      "suggested_atm_take_out": null,
      "tipping": { "value": 1, "description": "15% tipping" },
      "cashless": { "value": 1, "description": "Cards OK almost everywhere" },
      "tap_water": 1,
      "return_rate": null,
      "visitors_per_year": null,
      "tourists_now": null,
      "population": 46000,
      "gdp_per_capita": 57808,
      "density": null,
      "religious_government": 0,
      "male_percent": null,
      "female_percent": null,
      "apartment_listings": {
        "name": "Craigslist",
        "url": "http://craigslist.org",
        "logo": "https://logo.clearbit.com/craigslist.org"
      },
      "best_short_haul_air_carrier": null,
      "best_intl_air_carrier": {
        "name": "Delta",
        "url": "http://www.delta.com/",
        "logo": "https://logo.clearbit.com/www.delta.com/"
      },
      "best_taxi_app": {
        "name": "Uber",
        "url": "http://uber.com",
        "logo": null
      },
      "best_hospital": {
        "name": "Trinity Health Minot",
        "url": "http://www.trinityhealth.org/",
        "logo": "https://logo.clearbit.com/www.trinityhealth.org/"
      },
      "online_electronics_shop": {
        "name": "Amazon",
        "url": "https://amazon.com",
        "logo": "https://logo.clearbit.com/amazon.com"
      }
    },
    "costs": {
      "nomad_cost": 3439.35,
      "expat_cost": 2109.53,
      "family_cost": 5396.35,
      "local_cost": 1541.81,
      "hotel_price_median": 1964.2,
      "airbnb_median": 1244.76,
      "apartment_1bedroom": 1086.0,
      "coworking_hot_desk": 235.0,
      "water": null,
      "banana": null,
      "meat": null,
      "chicken_breast": null,
      "potato": null,
      "dinner": 16.0,
      "coca_cola": 2.0,
      "beer_in_cafe": 5.0,
      "international_school": 4000.0,
      "mobile_data": 4.0,
      "taxi_1km": 4.0
    }
  }
]