Spaces:
Sleeping
Sleeping
| import re | |
| import logging | |
| import string | |
| from collections import Counter | |
| logger = logging.getLogger(__name__) | |
| class TextImprover: | |
| """ | |
| Türkçe metinlerde iyileştirme ve öneriler sunan sınıf. | |
| Yazım hataları düzeltme, dilbilgisi önerileri ve okunabilirlik analizi yapar. | |
| """ | |
| def __init__(self): | |
| """Metin iyileştirme sınıfını başlatır""" | |
| # Türkçe'de yaygın yazım hataları ve düzeltmeleri | |
| self.common_typos = { | |
| # Büyük küçük harf duyarsız olarak yazım hataları | |
| 'bişey': 'bir şey', | |
| 'herşey': 'her şey', | |
| 'hiçbirşey': 'hiçbir şey', | |
| 'birsey': 'bir şey', | |
| 'hersey': 'her şey', | |
| 'hicbir': 'hiçbir', | |
| 'hicbirsey': 'hiçbir şey', | |
| 'yalnız': 'yalnız', | |
| 'bi': 'bir', | |
| 'gelicek': 'gelecek', | |
| 'gidiyom': 'gidiyorum', | |
| 'yapıyom': 'yapıyorum', | |
| 'biliyomusun': 'biliyor musun', | |
| 'napıyorsun': 'ne yapıyorsun', | |
| 'naber': 'ne haber', | |
| 'bilmiyomki': 'bilmiyorum ki', | |
| 'dicek': 'diyecek', | |
| 'dicem': 'diyeceğim', | |
| 'yicek': 'yiyecek', | |
| 'yicem': 'yiyeceğim' | |
| } | |
| # Türkçe'de sık kullanılan doldurma kelimeleri | |
| self.filler_words = [ | |
| 'yani', 'işte', 'şey', 'falan', 'filan', 'hani', 'mesela', | |
| 'aslında', 'ya', 'ki', 'de', 'da', 'ama', 'fakat', 'lakin', | |
| 'gerçekten', 'kesinlikle', 'tabii', 'tabi', 'şimdi', 'sonra' | |
| ] | |
| # Türkçe cümle karmaşıklığını değerlendirmek için parametreler | |
| self.max_sentence_length = 25 # Kelime sayısı | |
| self.max_word_length = 6 # Ortalama kelime uzunluğu | |
| # Okunabilirlik için kullanılacak parametreler | |
| # Türkçe için uyarlanmış Flesch Reading Ease formülü | |
| self.readability_thresholds = { | |
| 'çok_kolay': 90, | |
| 'kolay': 80, | |
| 'orta_kolay': 70, | |
| 'orta': 60, | |
| 'orta_zor': 50, | |
| 'zor': 30, | |
| 'çok_zor': 0 | |
| } | |
| logger.info("Metin iyileştirme modülü başlatıldı") | |
| def fix_typos(self, text): | |
| """ | |
| Metindeki yaygın yazım hatalarını düzeltir | |
| Args: | |
| text: Düzeltilecek metin | |
| Returns: | |
| dict: { | |
| 'corrected_text': str, # Düzeltilmiş metin | |
| 'corrections': list, # Yapılan düzeltmeler listesi | |
| 'correction_count': int # Düzeltme sayısı | |
| } | |
| """ | |
| corrected_text = text | |
| corrections = [] | |
| # Önce metni kelimelere ayır | |
| words = re.findall(r'\b\w+\b', text.lower()) | |
| # Her kelimeyi kontrol et | |
| for word in words: | |
| if word.lower() in self.common_typos: | |
| correct_word = self.common_typos[word.lower()] | |
| # Kelimenin metindeki tüm örneklerini düzelt | |
| # \b ile kelime sınırlarını belirt | |
| pattern = r'\b' + re.escape(word) + r'\b' | |
| corrected_text = re.sub(pattern, correct_word, corrected_text, flags=re.IGNORECASE) | |
| corrections.append(f"'{word}' -> '{correct_word}'") | |
| return { | |
| 'corrected_text': corrected_text, | |
| 'corrections': corrections, | |
| 'correction_count': len(corrections) | |
| } | |
| def check_grammar(self, text): | |
| """ | |
| Metindeki temel dilbilgisi sorunlarını kontrol eder | |
| Args: | |
| text: Kontrol edilecek metin | |
| Returns: | |
| dict: { | |
| 'issues': list, # Tespit edilen sorunlar listesi | |
| 'suggestions': list, # Öneriler listesi | |
| 'issue_count': int # Sorun sayısı | |
| } | |
| """ | |
| issues = [] | |
| suggestions = [] | |
| # Cümlelere ayır | |
| sentences = re.split(r'[.!?]+', text) | |
| sentences = [s.strip() for s in sentences if s.strip()] | |
| for i, sentence in enumerate(sentences): | |
| # Büyük harfle başlama kontrolü | |
| if sentence and not sentence[0].isupper(): | |
| issues.append(f"Cümle {i + 1}: Büyük harfle başlamıyor") | |
| suggestions.append(f"Cümle {i + 1}: '{sentence[0]}' -> '{sentence[0].upper()}'") | |
| # Cümle uzunluğu kontrolü | |
| words = sentence.split() | |
| if len(words) > self.max_sentence_length: | |
| issues.append(f"Cümle {i + 1}: Çok uzun ({len(words)} kelime)") | |
| suggestions.append(f"Cümle {i + 1}: Daha kısa cümlelere bölmeyi düşünün") | |
| # Noktalama kontrolü | |
| if i < len(sentences) - 1: # Son cümle değilse | |
| if not text.find(sentence + ".") and not text.find(sentence + "!") and not text.find(sentence + "?"): | |
| issues.append(f"Cümle {i + 1}: Noktalama işareti eksik olabilir") | |
| suggestions.append(f"Cümle {i + 1}: Cümle sonuna uygun noktalama işareti ekleyin") | |
| return { | |
| 'issues': issues, | |
| 'suggestions': suggestions, | |
| 'issue_count': len(issues) | |
| } | |
| def reduce_filler_words(self, text): | |
| """ | |
| Metindeki doldurma kelimelerini tespit eder ve azaltma önerileri sunar | |
| Args: | |
| text: İyileştirilecek metin | |
| Returns: | |
| dict: { | |
| 'filler_words': list, # Bulunan doldurma kelimeleri | |
| 'filler_count': int, # Doldurma kelimesi sayısı | |
| 'suggested_text': str # Önerilen iyileştirilmiş metin | |
| } | |
| """ | |
| # Metindeki kelimeleri bul | |
| words = re.findall(r'\b\w+\b', text.lower()) | |
| # Doldurma kelimelerini ve sayılarını say | |
| filler_counter = Counter() | |
| for word in words: | |
| if word.lower() in self.filler_words: | |
| filler_counter[word.lower()] += 1 | |
| # Metni kelime kelime işle ve fazla doldurma kelimelerini kaldır | |
| suggested_text = text | |
| for filler_word, count in filler_counter.items(): | |
| if count > 1: # Birden fazla geçiyorsa | |
| # Her bir örneği bul | |
| occurrences = list(re.finditer(r'\b' + re.escape(filler_word) + r'\b', suggested_text, re.IGNORECASE)) | |
| # İlk geçtiği yer hariç diğerlerini kaldır | |
| for occurrence in occurrences[1:]: | |
| start, end = occurrence.span() | |
| # Eğer kelimenin önünde veya arkasında boşluk varsa, onu da kaldır | |
| if start > 0 and suggested_text[start - 1] == ' ': | |
| start -= 1 | |
| suggested_text = suggested_text[:start] + suggested_text[end:] | |
| return { | |
| 'filler_words': list(filler_counter.keys()), | |
| 'filler_count': sum(filler_counter.values()), | |
| 'suggested_text': suggested_text | |
| } | |
| def calculate_readability(self, text): | |
| """ | |
| Metnin okunabilirlik skorunu hesaplar (Türkçe'ye uyarlanmış Flesch Reading Ease) | |
| Args: | |
| text: Değerlendirilecek metin | |
| Returns: | |
| dict: { | |
| 'score': float, # Okunabilirlik skoru (0-100) | |
| 'level': str, # Okunabilirlik seviyesi | |
| 'avg_sentence_length': float, # Ortalama cümle uzunluğu | |
| 'avg_word_length': float # Ortalama kelime uzunluğu | |
| } | |
| """ | |
| # Cümleleri ve kelimeleri ayır | |
| sentences = re.split(r'[.!?]+', text) | |
| sentences = [s.strip() for s in sentences if s.strip()] | |
| total_words = 0 | |
| total_syllables = 0 | |
| for sentence in sentences: | |
| words = re.findall(r'\b\w+\b', sentence) | |
| total_words += len(words) | |
| # Türkçe heceleri kabaca hesapla (sesli harf sayısı) | |
| for word in words: | |
| # Türkçedeki sesli harfler | |
| vowels = 'aeıioöuüAEIİOÖUÜ' | |
| syllable_count = sum(1 for char in word if char in vowels) | |
| # En az bir hece olmalı | |
| syllable_count = max(1, syllable_count) | |
| total_syllables += syllable_count | |
| # Hesaplamalar | |
| if len(sentences) == 0 or total_words == 0: | |
| return { | |
| 'score': 100, # Boş metin - en kolay | |
| 'level': 'çok_kolay', | |
| 'avg_sentence_length': 0, | |
| 'avg_word_length': 0 | |
| } | |
| avg_sentence_length = total_words / len(sentences) | |
| avg_syllables_per_word = total_syllables / total_words | |
| # Türkçe için uyarlanmış Flesch Reading Ease | |
| # (orijinal formül: 206.835 - 1.015 * ASL - 84.6 * ASW) | |
| # Türkçe için katsayılar ayarlandı | |
| readability_score = 206.835 - (1.3 * avg_sentence_length) - (60.0 * avg_syllables_per_word) | |
| # Skoru 0-100 aralığına sınırla | |
| readability_score = max(0, min(100, readability_score)) | |
| # Seviyeyi belirle | |
| level = 'çok_zor' | |
| for threshold_level, threshold_value in sorted(self.readability_thresholds.items(), key=lambda x: x[1]): | |
| if readability_score >= threshold_value: | |
| level = threshold_level | |
| break | |
| return { | |
| 'score': float(readability_score), | |
| 'level': level, | |
| 'avg_sentence_length': float(avg_sentence_length), | |
| 'avg_word_length': float(avg_syllables_per_word) | |
| } | |
| def improve_text(self, text): | |
| """ | |
| Metni kapsamlı şekilde analiz eder ve iyileştirme önerileri sunar | |
| Args: | |
| text: İyileştirilecek metin | |
| Returns: | |
| dict: Tüm iyileştirme analizlerini içeren sonuçlar | |
| """ | |
| if not text or len(text.strip()) == 0: | |
| return { | |
| 'corrected_text': text, | |
| 'suggestions': [], | |
| 'readability': { | |
| 'score': 100, | |
| 'level': 'çok_kolay' | |
| }, | |
| 'improvement_count': 0 | |
| } | |
| try: | |
| # Yazım hatalarını düzelt | |
| typo_results = self.fix_typos(text) | |
| # Dilbilgisi kontrolü | |
| grammar_results = self.check_grammar(typo_results['corrected_text']) | |
| # Doldurma kelimelerini azalt | |
| filler_results = self.reduce_filler_words(typo_results['corrected_text']) | |
| # Okunabilirlik hesapla | |
| readability_results = self.calculate_readability(text) | |
| # Tüm önerileri birleştir | |
| all_suggestions = [] | |
| all_suggestions.extend([f"Yazım düzeltmesi: {correction}" for correction in typo_results['corrections']]) | |
| all_suggestions.extend( | |
| [f"Dilbilgisi önerisi: {suggestion}" for suggestion in grammar_results['suggestions']]) | |
| if filler_results['filler_count'] > 0: | |
| all_suggestions.append(f"Doldurma kelimelerini azaltın: {', '.join(filler_results['filler_words'])}") | |
| # Okunabilirlik önerisi | |
| if readability_results['score'] < 60: # Orta seviyenin altında ise | |
| if readability_results['avg_sentence_length'] > 15: | |
| all_suggestions.append("Daha kısa cümleler kullanın (ortalama cümle uzunluğu yüksek)") | |
| if readability_results['avg_word_length'] > 2.5: | |
| all_suggestions.append("Daha basit kelimeler kullanmayı deneyin (ortalama hece sayısı yüksek)") | |
| # Birleştirilmiş sonuç | |
| return { | |
| 'original_text': text, | |
| 'corrected_text': typo_results['corrected_text'], | |
| 'improved_text': filler_results['suggested_text'], | |
| 'suggestions': all_suggestions, | |
| 'readability': { | |
| 'score': readability_results['score'], | |
| 'level': readability_results['level'], | |
| 'avg_sentence_length': readability_results['avg_sentence_length'] | |
| }, | |
| 'improvement_count': len(all_suggestions) | |
| } | |
| except Exception as e: | |
| logger.error(f"Metin iyileştirme sırasında hata: {str(e)}") | |
| return { | |
| 'original_text': text, | |
| 'corrected_text': text, | |
| 'improved_text': text, | |
| 'suggestions': ["Metin analizi sırasında bir hata oluştu"], | |
| 'readability': { | |
| 'score': 0, | |
| 'level': 'bilinmiyor' | |
| }, | |
| 'improvement_count': 0 | |
| } |