kececinumbers 0.6.8__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kececinumbers/__init__.py CHANGED
@@ -22,7 +22,7 @@ import warnings
22
22
  # importlib.reload(kececinumbers) # F821 undefined name 'kececinumbers'
23
23
 
24
24
  # Paket sürüm numarası
25
- __version__ = "0.6.8"
25
+ __version__ = "0.7.0"
26
26
  __author__ = "Mehmet Keçeci"
27
27
  __email__ = "mkececi@yaani.com"
28
28
 
kececinumbers/_version.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # _version.py
3
3
 
4
- __version__ = "0.6.8"
4
+ __version__ = "0.7.0"
5
5
  __license__ = "MIT"
6
6
  __description__ = "Keçeci Numbers: An Exploration of a Dynamic Sequence Across Diverse Number Sets."
7
7
  __author__ = "Mehmet Keçeci"
@@ -33,7 +33,7 @@ import collections
33
33
  from dataclasses import dataclass
34
34
  from fractions import Fraction
35
35
  import math
36
- from matplotlib.gridspec import GridSpec
36
+ #from matplotlib.gridspec import GridSpec
37
37
  import matplotlib.pyplot as plt
38
38
  import numbers
39
39
  #from numbers import Real
@@ -49,6 +49,13 @@ from typing import Any, Dict, List, Optional, Tuple
49
49
 
50
50
  # numpy ve diğer Keçeci tipleri için gerekli importlar
51
51
  # Eğer bu kütüphaneler yüklü değilse, pip install numpy gibi komutlarla yüklemeniz gerekebilir.
52
+ try:
53
+ from matplotlib.gridspec import GridSpec
54
+ except ModuleNotFoundError:
55
+ import matplotlib
56
+ print(f"Matplotlib path: {matplotlib.__file__}")
57
+ from matplotlib.gridspec import GridSpec
58
+
52
59
  try:
53
60
  import numpy as np
54
61
  # numpy.quaternion'ın eski adı np.quaternion. Yeni versiyonlarda quaternion modülü ayrı olabilir.
@@ -63,7 +70,7 @@ except ImportError:
63
70
 
64
71
 
65
72
  # ==============================================================================
66
- # --- MODULE CONSTANTS: KEÇECI NUMBER TYPES ---
73
+ # --- MODULE CONSTANTS: Keçeci NUMBER TYPES ---
67
74
  # ==============================================================================
68
75
  TYPE_POSITIVE_REAL = 1
69
76
  TYPE_NEGATIVE_REAL = 2
@@ -82,8 +89,6 @@ TYPE_CLIFFORD = 14
82
89
  TYPE_DUAL = 15
83
90
  TYPE_SPLIT_COMPLEX = 16
84
91
 
85
-
86
-
87
92
  # ==============================================================================
88
93
  # --- CUSTOM NUMBER CLASS DEFINITIONS ---
89
94
  # ==============================================================================
@@ -865,10 +870,56 @@ def _extract_numeric_part(s: str) -> str:
865
870
  # Hiç sayı bulunamazsa orijinal string'i döndür
866
871
  return s
867
872
 
868
- def _parse_complex(s: str) -> complex:
869
- """Bir string'i complex sayıya dönüştürür.
873
+ def _parse_complex(s) -> complex:
874
+ """Bir string'i veya sayıyı complex sayıya dönüştürür.
870
875
  "real,imag", "real+imag(i/j)", "real", "imag(i/j)" formatlarını destekler.
876
+ Float ve int tiplerini de doğrudan kabul eder.
871
877
  """
878
+ # Eğer zaten complex sayıysa doğrudan döndür
879
+ if isinstance(s, complex):
880
+ return s
881
+
882
+ # Eğer float veya int ise doğrudan complex'e dönüştür
883
+ if isinstance(s, (float, int)):
884
+ return complex(s)
885
+
886
+ # String işlemleri için önce string'e dönüştür
887
+ if isinstance(s, str):
888
+ s = s.strip().replace('J', 'j').replace('i', 'j') # Hem J hem i yerine j kullan
889
+ else:
890
+ s = str(s).strip().replace('J', 'j').replace('i', 'j')
891
+
892
+ # 1. Eğer "real,imag" formatındaysa
893
+ if ',' in s:
894
+ parts = s.split(',')
895
+ if len(parts) == 2:
896
+ try:
897
+ return complex(float(parts[0]), float(parts[1]))
898
+ except ValueError:
899
+ pass # Devam et
900
+
901
+ # 2. Python'ın kendi complex() dönüştürücüsünü kullanmayı dene (örn: "1+2j", "3j", "-5")
902
+ try:
903
+ return complex(s)
904
+ except ValueError:
905
+ # 3. Sadece real kısmı varsa (örn: "5")
906
+ try:
907
+ return complex(float(s), 0)
908
+ except ValueError:
909
+ # 4. Sadece sanal kısmı varsa (örn: "2j", "j")
910
+ if s.endswith('j'):
911
+ try:
912
+ imag_val = float(s[:-1]) if s[:-1] else 1.0 # "j" -> 1.0j
913
+ return complex(0, imag_val)
914
+ except ValueError:
915
+ pass
916
+
917
+ raise ValueError(f"Geçersiz kompleks sayı formatı: '{s}'")
918
+ """
919
+ def _parse_complex(s: str) -> complex:
920
+ #Bir string'i complex sayıya dönüştürür.
921
+ # "real,imag", "real+imag(i/j)", "real", "imag(i/j)" formatlarını destekler.
922
+
872
923
  s = s.strip().replace('J', 'j').replace('i', 'j') # Hem J hem i yerine j kullan
873
924
 
874
925
  # 1. Eğer "real,imag" formatındaysa
@@ -897,6 +948,7 @@ def _parse_complex(s: str) -> complex:
897
948
  pass
898
949
 
899
950
  raise ValueError(f"Geçersiz kompleks sayı formatı: '{s}'")
951
+ """
900
952
 
901
953
  def convert_to_float(value):
902
954
  """Convert various Keçeci number types to a float or raise an error if not possible."""
@@ -961,8 +1013,20 @@ def safe_add(added_value, ask_unit, direction):
961
1013
  raise TypeError(f"{msg} → {type(e).__name__}: {e}") from e
962
1014
 
963
1015
 
964
- def _parse_neutrosophic(s: str) -> Tuple[float, float, float]:
1016
+ def _parse_neutrosophic(s) -> Tuple[float, float, float]:
965
1017
  """Parses neutrosophic string into (t, i, f) tuple."""
1018
+ # Eğer zaten tuple ise doğrudan döndür
1019
+ if isinstance(s, (tuple, list)) and len(s) >= 3:
1020
+ return float(s[0]), float(s[1]), float(s[2])
1021
+
1022
+ # Sayısal tipse sadece t değeri olarak işle
1023
+ if isinstance(s, (float, int, complex)):
1024
+ return float(s), 0.0, 0.0
1025
+
1026
+ # String işlemleri için önce string'e dönüştür
1027
+ if not isinstance(s, str):
1028
+ s = str(s)
1029
+
966
1030
  s_clean = s.strip().replace(" ", "").upper()
967
1031
 
968
1032
  # VİRGÜL formatı: t,i,f (3 parametre)
@@ -1004,8 +1068,20 @@ def _parse_neutrosophic(s: str) -> Tuple[float, float, float]:
1004
1068
  except ValueError:
1005
1069
  return 0.0, 0.0, 0.0 # Default
1006
1070
 
1007
- def _parse_hyperreal(s: str) -> Tuple[float, float]:
1071
+ def _parse_hyperreal(s) -> Tuple[float, float]:
1008
1072
  """Parses hyperreal string into (finite, infinitesimal) tuple."""
1073
+ # Eğer zaten tuple ise doğrudan döndür
1074
+ if isinstance(s, (tuple, list)) and len(s) >= 2:
1075
+ return float(s[0]), float(s[1])
1076
+
1077
+ # Sayısal tipse sadece finite değeri olarak işle
1078
+ if isinstance(s, (float, int, complex)):
1079
+ return float(s), 0.0
1080
+
1081
+ # String işlemleri için önce string'e dönüştür
1082
+ if not isinstance(s, str):
1083
+ s = str(s)
1084
+
1009
1085
  s_clean = s.strip().replace(" ", "")
1010
1086
 
1011
1087
  # VİRGÜL formatı: finite,infinitesimal
@@ -1038,10 +1114,20 @@ def _parse_hyperreal(s: str) -> Tuple[float, float]:
1038
1114
  except ValueError:
1039
1115
  return 0.0, 0.0 # Default
1040
1116
 
1041
- def _parse_quaternion_from_csv(s: str) -> np.quaternion:
1042
- """Virgülle ayrılmış string'i Quaternion'a dönüştürür.
1043
- "w,x,y,z" veya sadece "w" (skaler) formatlarını destekler.
1044
- """
1117
+ def _parse_quaternion_from_csv(s) -> np.quaternion:
1118
+ """Virgülle ayrılmış string'i veya sayıyı Quaternion'a dönüştürür."""
1119
+ # Eğer zaten quaternion ise doğrudan döndür
1120
+ if isinstance(s, np.quaternion):
1121
+ return s
1122
+
1123
+ # Sayısal tipse skaler quaternion olarak işle
1124
+ if isinstance(s, (float, int, complex)):
1125
+ return np.quaternion(float(s), 0, 0, 0)
1126
+
1127
+ # String işlemleri için önce string'e dönüştür
1128
+ if not isinstance(s, str):
1129
+ s = str(s)
1130
+
1045
1131
  s = s.strip()
1046
1132
  parts_str = s.split(',')
1047
1133
 
@@ -1058,15 +1144,29 @@ def _parse_quaternion_from_csv(s: str) -> np.quaternion:
1058
1144
  else:
1059
1145
  raise ValueError(f"Geçersiz quaternion formatı. 1 veya 4 bileşen bekleniyor: '{s}'")
1060
1146
 
1061
-
1062
- def _has_comma_format(s: str) -> bool:
1147
+ def _has_comma_format(s) -> bool:
1063
1148
  """String'in virgül içerip içermediğini kontrol eder."""
1149
+ if not isinstance(s, str):
1150
+ s = str(s)
1064
1151
  return ',' in s
1065
1152
 
1066
- def _parse_neutrosophic_bicomplex(s: str) -> NeutrosophicBicomplexNumber:
1153
+ def _parse_neutrosophic_bicomplex(s) -> NeutrosophicBicomplexNumber:
1067
1154
  """
1068
- Parses string like "a,b,c,d,e,f,g,h" into 8 components.
1155
+ Parses string or numbers into NeutrosophicBicomplexNumber.
1069
1156
  """
1157
+ # Eğer zaten NeutrosophicBicomplexNumber ise doğrudan döndür
1158
+ if isinstance(s, NeutrosophicBicomplexNumber):
1159
+ return s
1160
+
1161
+ # Sayısal tipse tüm bileşenler 0, sadece ilk bileşen değerli
1162
+ if isinstance(s, (float, int, complex)):
1163
+ values = [float(s)] + [0.0] * 7
1164
+ return NeutrosophicBicomplexNumber(*values)
1165
+
1166
+ # String işlemleri için önce string'e dönüştür
1167
+ if not isinstance(s, str):
1168
+ s = str(s)
1169
+
1070
1170
  try:
1071
1171
  parts = s.split(',')
1072
1172
  if len(parts) != 8:
@@ -1075,9 +1175,167 @@ def _parse_neutrosophic_bicomplex(s: str) -> NeutrosophicBicomplexNumber:
1075
1175
  return NeutrosophicBicomplexNumber(*values)
1076
1176
  except Exception as e:
1077
1177
  raise ValueError(f"Invalid NeutrosophicBicomplex format: '{s}' → {e}")
1178
+ """
1179
+ def _parse_neutrosophic(s: str) -> Tuple[float, float, float]:
1180
+ #Parses neutrosophic string into (t, i, f) tuple.
1181
+ s_clean = s.strip().replace(" ", "").upper()
1182
+
1183
+ # VİRGÜL formatı: t,i,f (3 parametre)
1184
+ if ',' in s_clean:
1185
+ parts = s_clean.split(',')
1186
+ try:
1187
+ if len(parts) >= 3:
1188
+ return float(parts[0]), float(parts[1]), float(parts[2])
1189
+ elif len(parts) == 2:
1190
+ return float(parts[0]), float(parts[1]), 0.0
1191
+ elif len(parts) == 1:
1192
+ return float(parts[0]), 0.0, 0.0
1193
+ except ValueError:
1194
+ pass
1195
+
1196
+ # Eski formatları destekle
1197
+ try:
1198
+ if 'I' in s_clean or 'F' in s_clean:
1199
+ # Basit parsing
1200
+ t_part = s_clean
1201
+ i_val, f_val = 0.0, 0.0
1202
+
1203
+ if 'I' in s_clean:
1204
+ parts = s_clean.split('I')
1205
+ t_part = parts[0]
1206
+ i_val = float(parts[1]) if parts[1] and parts[1] not in ['', '+', '-'] else 1.0
1207
+
1208
+ if 'F' in t_part:
1209
+ parts = t_part.split('F')
1210
+ t_val = float(parts[0]) if parts[0] and parts[0] not in ['', '+', '-'] else 0.0
1211
+ f_val = float(parts[1]) if len(parts) > 1 and parts[1] not in ['', '+', '-'] else 1.0
1212
+ else:
1213
+ t_val = float(t_part) if t_part not in ['', '+', '-'] else 0.0
1214
+
1215
+ return t_val, i_val, f_val
1216
+ else:
1217
+ # Sadece sayısal değer
1218
+ return float(s_clean), 0.0, 0.0
1219
+ except ValueError:
1220
+ return 0.0, 0.0, 0.0 # Default
1221
+ """
1222
+ """
1223
+ def _parse_hyperreal(s: str) -> Tuple[float, float]:
1224
+ #Parses hyperreal string into (finite, infinitesimal) tuple.
1225
+ s_clean = s.strip().replace(" ", "")
1226
+
1227
+ # VİRGÜL formatı: finite,infinitesimal
1228
+ if ',' in s_clean:
1229
+ parts = s_clean.split(',')
1230
+ if len(parts) >= 2:
1231
+ try:
1232
+ return float(parts[0]), float(parts[1])
1233
+ except ValueError:
1234
+ pass
1235
+ elif len(parts) == 1:
1236
+ try:
1237
+ return float(parts[0]), 0.0
1238
+ except ValueError:
1239
+ pass
1240
+
1241
+ # Eski 'a+be' formatını destekle
1242
+ if 'e' in s_clean:
1243
+ try:
1244
+ parts = s_clean.split('e')
1245
+ finite = float(parts[0]) if parts[0] not in ['', '+', '-'] else 0.0
1246
+ infinitesimal = float(parts[1]) if len(parts) > 1 and parts[1] not in ['', '+', '-'] else 1.0
1247
+ return finite, infinitesimal
1248
+ except ValueError:
1249
+ pass
1250
+
1251
+ # Sadece sayısal değer
1252
+ try:
1253
+ return float(s_clean), 0.0
1254
+ except ValueError:
1255
+ return 0.0, 0.0 # Default
1256
+ """
1257
+ """
1258
+ def _parse_quaternion_from_csv(s: str) -> np.quaternion:
1259
+ #Virgülle ayrılmış string'i Quaternion'a dönüştürür.
1260
+ #"w,x,y,z" veya sadece "w" (skaler) formatlarını destekler.
1078
1261
 
1262
+ s = s.strip()
1263
+ parts_str = s.split(',')
1264
+
1265
+ # Tüm parçaları float'a dönüştürmeyi dene
1266
+ try:
1267
+ parts_float = [float(p.strip()) for p in parts_str]
1268
+ except ValueError:
1269
+ raise ValueError(f"Quaternion bileşenleri sayı olmalı: '{s}'")
1270
+
1271
+ if len(parts_float) == 4:
1272
+ return np.quaternion(*parts_float)
1273
+ elif len(parts_float) == 1: # Sadece skaler değer
1274
+ return np.quaternion(parts_float[0], 0, 0, 0)
1275
+ else:
1276
+ raise ValueError(f"Geçersiz quaternion formatı. 1 veya 4 bileşen bekleniyor: '{s}'")
1277
+ """
1278
+ """
1279
+ def _has_comma_format(s: str) -> bool:
1280
+ #String'in virgül içerip içermediğini kontrol eder.
1281
+ return ',' in s
1282
+ """
1283
+ """
1284
+ def _parse_neutrosophic_bicomplex(s: str) -> NeutrosophicBicomplexNumber:
1285
+
1286
+ #Parses string like "a,b,c,d,e,f,g,h" into 8 components.
1287
+
1288
+ try:
1289
+ parts = s.split(',')
1290
+ if len(parts) != 8:
1291
+ raise ValueError(f"Expected 8 components, got {len(parts)}")
1292
+ values = [float(part.strip()) for part in parts]
1293
+ return NeutrosophicBicomplexNumber(*values)
1294
+ except Exception as e:
1295
+ raise ValueError(f"Invalid NeutrosophicBicomplex format: '{s}' → {e}")
1296
+ """
1297
+
1298
+ def _parse_octonion(s) -> OctonionNumber:
1299
+ """String'i veya sayıyı OctonionNumber'a dönüştürür.
1300
+ w,x,y,z,e,f,g,h:e0,e1,e2,e3,e4,e5,e6,e7
1301
+ """
1302
+ # Eğer zaten OctonionNumber ise doğrudan döndür
1303
+ if isinstance(s, OctonionNumber):
1304
+ return s
1305
+
1306
+ # Eğer sayısal tipse (float, int, complex) skaler olarak işle
1307
+ if isinstance(s, (float, int, complex)):
1308
+ scalar = float(s)
1309
+ return OctonionNumber(scalar, 0, 0, 0, 0, 0, 0, 0)
1310
+
1311
+ # String işlemleri için önce string'e dönüştür
1312
+ if not isinstance(s, str):
1313
+ s = str(s)
1314
+
1315
+ s_clean = s.strip()
1316
+
1317
+ # Eğer virgül içermiyorsa, skaler olarak kabul et
1318
+ if ',' not in s_clean:
1319
+ try:
1320
+ scalar = float(s_clean)
1321
+ return OctonionNumber(scalar, 0, 0, 0, 0, 0, 0, 0)
1322
+ except ValueError:
1323
+ raise ValueError(f"Invalid octonion format: '{s}'")
1324
+
1325
+ # Virgülle ayrılmışsa
1326
+ try:
1327
+ parts = [float(p.strip()) for p in s_clean.split(',')]
1328
+ if len(parts) == 8:
1329
+ return OctonionNumber(*parts) # 8 parametre olarak gönder
1330
+ else:
1331
+ # Eksik veya fazla bileşen için default
1332
+ scalar = parts[0] if parts else 0.0
1333
+ return OctonionNumber(scalar, 0, 0, 0, 0, 0, 0, 0)
1334
+ except ValueError as e:
1335
+ raise ValueError(f"Invalid octonion format: '{s}'") from e
1336
+ """
1079
1337
  def _parse_octonion(s: str) -> OctonionNumber:
1080
- """'w,x,y,z,e,f,g,h' formatındaki stringi OctonionNumber'a çevirir."""
1338
+ #'w,x,y,z,e,f,g,h' formatındaki stringi OctonionNumber'a çevirir.
1081
1339
  s_clean = s.strip()
1082
1340
 
1083
1341
  # Eğer virgül içermiyorsa, skaler olarak kabul et
@@ -1099,10 +1357,42 @@ def _parse_octonion(s: str) -> OctonionNumber:
1099
1357
  return OctonionNumber(scalar, 0, 0, 0, 0, 0, 0, 0)
1100
1358
  except ValueError as e:
1101
1359
  raise ValueError(f"Invalid octonion format: '{s}'") from e
1360
+ """
1102
1361
 
1362
+ def _parse_sedenion(s) -> SedenionNumber:
1363
+ """String'i veya sayıyı SedenionNumber'a dönüştürür."""
1364
+ # Eğer zaten SedenionNumber ise doğrudan döndür
1365
+ if isinstance(s, SedenionNumber):
1366
+ return s
1367
+
1368
+ # Eğer sayısal tipse (float, int, complex) skaler olarak işle
1369
+ if isinstance(s, (float, int, complex)):
1370
+ scalar_val = float(s)
1371
+ return SedenionNumber([scalar_val] + [0.0] * 15)
1372
+
1373
+ # String işlemleri için önce string'e dönüştür
1374
+ if not isinstance(s, str):
1375
+ s = str(s)
1376
+
1377
+ s = s.strip()
1378
+ parts = [p.strip() for p in s.split(',')]
1103
1379
 
1380
+ if len(parts) == 16:
1381
+ try:
1382
+ return SedenionNumber(list(map(float, parts)))
1383
+ except ValueError as e:
1384
+ raise ValueError(f"Geçersiz sedenion bileşen değeri: '{s}' -> {e}") from e
1385
+ elif len(parts) == 1: # Sadece skaler değer girildiğinde
1386
+ try:
1387
+ scalar_val = float(parts[0])
1388
+ return SedenionNumber([scalar_val] + [0.0] * 15)
1389
+ except ValueError as e:
1390
+ raise ValueError(f"Geçersiz skaler sedenion değeri: '{s}' -> {e}") from e
1391
+
1392
+ raise ValueError(f"Sedenion için 16 bileşen veya tek skaler bileşen gerekir. Verilen: '{s}' ({len(parts)} bileşen)")
1393
+ """
1104
1394
  def _parse_sedenion(s: str) -> SedenionNumber:
1105
- """String'i SedenionNumber'a dönüştürür."""
1395
+ #String'i SedenionNumber'a dönüştürür.
1106
1396
  s = s.strip()
1107
1397
  parts = [p.strip() for p in s.split(',')]
1108
1398
 
@@ -1119,9 +1409,63 @@ def _parse_sedenion(s: str) -> SedenionNumber:
1119
1409
  raise ValueError(f"Geçersiz skaler sedenion değeri: '{s}' -> {e}") from e
1120
1410
 
1121
1411
  raise ValueError(f"Sedenion için 16 bileşen veya tek skaler bileşen gerekir. Verilen: '{s}' ({len(parts)} bileşen)")
1412
+ """
1122
1413
 
1414
+ def _parse_clifford(s) -> CliffordNumber:
1415
+ """Algebraik string'i veya sayıyı CliffordNumber'a dönüştürür (ör: '1.0+2.0e1')."""
1416
+ # Eğer zaten CliffordNumber ise doğrudan döndür
1417
+ if isinstance(s, CliffordNumber):
1418
+ return s
1419
+
1420
+ # Eğer sayısal tipse (float, int, complex) skaler olarak işle
1421
+ if isinstance(s, (float, int, complex)):
1422
+ return CliffordNumber({'': float(s)})
1423
+
1424
+ # String işlemleri için önce string'e dönüştür
1425
+ if not isinstance(s, str):
1426
+ s = str(s)
1427
+
1428
+ s = s.strip().replace(' ', '')
1429
+ basis_dict = {'': 0.0} # Skaler kısım
1430
+
1431
+ terms_pattern = re.compile(r"([+-]?)(\d*\.?\d+(?:[eE][+-]?\d+)?)?(e\d*)?")
1432
+ remaining_s = s
1433
+
1434
+ while remaining_s:
1435
+ match = terms_pattern.match(remaining_s)
1436
+ if not match or (match.group(2) is None and match.group(3) is None):
1437
+ if remaining_s.startswith('+') or remaining_s.startswith('-'):
1438
+ current_sign = remaining_s[0]
1439
+ remaining_s = remaining_s[1:]
1440
+ if not remaining_s:
1441
+ coeff = 1.0 if current_sign == '+' else -1.0
1442
+ basis_dict[''] = basis_dict.get('', 0.0) + coeff
1443
+ continue
1444
+ raise ValueError(f"Geçersiz Clifford terim formatı: '{remaining_s}'")
1445
+
1446
+ sign_str, coeff_str, basis_str_with_e = match.groups()
1447
+ current_sign = 1.0
1448
+ if sign_str == '-': current_sign = -1.0
1449
+
1450
+ coeff = 1.0
1451
+ if coeff_str: coeff = float(coeff_str)
1452
+ elif not sign_str: coeff = 1.0
1453
+ elif sign_str and not coeff_str: coeff = 1.0
1454
+
1455
+ coeff *= current_sign
1456
+
1457
+ if basis_str_with_e:
1458
+ basis_key = basis_str_with_e.lstrip('e')
1459
+ basis_dict[basis_key] = basis_dict.get(basis_key, 0.0) + coeff
1460
+ else:
1461
+ basis_dict[''] = basis_dict.get('', 0.0) + coeff
1462
+
1463
+ remaining_s = remaining_s[match.end():]
1464
+
1465
+ return CliffordNumber(basis_dict)
1466
+ """
1123
1467
  def _parse_clifford(s: str) -> CliffordNumber:
1124
- """Algebraik string'i CliffordNumber'a dönüştürür (ör: '1.0+2.0e1')."""
1468
+ #Algebraik string'i CliffordNumber'a dönüştürür (ör: '1.0+2.0e1').
1125
1469
  s = s.strip().replace(' ', '')
1126
1470
  basis_dict = {'': 0.0} # Skaler kısım
1127
1471
 
@@ -1160,9 +1504,41 @@ def _parse_clifford(s: str) -> CliffordNumber:
1160
1504
  remaining_s = remaining_s[match.end():]
1161
1505
 
1162
1506
  return CliffordNumber(basis_dict)
1507
+ """
1163
1508
 
1509
+ def _parse_dual(s) -> DualNumber:
1510
+ """String'i veya sayıyı DualNumber'a dönüştürür."""
1511
+ # Eğer zaten DualNumber ise doğrudan döndür
1512
+ if isinstance(s, DualNumber):
1513
+ return s
1514
+
1515
+ # Eğer sayısal tipse (float, int, complex) real kısım olarak işle
1516
+ if isinstance(s, (float, int, complex)):
1517
+ return DualNumber(float(s), 0.0)
1518
+
1519
+ # String işlemleri için önce string'e dönüştür
1520
+ if not isinstance(s, str):
1521
+ s = str(s)
1522
+
1523
+ s = s.strip()
1524
+ parts = [p.strip() for p in s.split(',')]
1525
+
1526
+ # Sadece ilk iki bileşeni al
1527
+ if len(parts) >= 2:
1528
+ try:
1529
+ return DualNumber(float(parts[0]), float(parts[1]))
1530
+ except ValueError:
1531
+ pass
1532
+ elif len(parts) == 1: # Sadece real kısım verilmiş
1533
+ try:
1534
+ return DualNumber(float(parts[0]), 0.0)
1535
+ except ValueError:
1536
+ pass
1537
+
1538
+ raise ValueError(f"Geçersiz Dual sayı formatı: '{s}' (Real, Dual veya sadece Real bekleniyor)")
1539
+ """
1164
1540
  def _parse_dual(s: str) -> DualNumber:
1165
- """Virgülle ayrılmış string'i DualNumber'a dönüştürür."""
1541
+ #Virgülle ayrılmış string'i DualNumber'a dönüştürür.
1166
1542
  s = s.strip()
1167
1543
  parts = [p.strip() for p in s.split(',')]
1168
1544
 
@@ -1179,9 +1555,22 @@ def _parse_dual(s: str) -> DualNumber:
1179
1555
  pass
1180
1556
 
1181
1557
  raise ValueError(f"Geçersiz Dual sayı formatı: '{s}' (Real, Dual veya sadece Real bekleniyor)")
1558
+ """
1182
1559
 
1183
- def _parse_splitcomplex(s: str) -> SplitcomplexNumber:
1184
- """Virgülle ayrılmış string'i SplitcomplexNumber'a dönüştürür."""
1560
+ def _parse_splitcomplex(s) -> SplitcomplexNumber:
1561
+ """String'i veya sayıyı SplitcomplexNumber'a dönüştürür."""
1562
+ # Eğer zaten SplitcomplexNumber ise doğrudan döndür
1563
+ if isinstance(s, SplitcomplexNumber):
1564
+ return s
1565
+
1566
+ # Eğer sayısal tipse (float, int, complex) real kısım olarak işle
1567
+ if isinstance(s, (float, int, complex)):
1568
+ return SplitcomplexNumber(float(s), 0.0)
1569
+
1570
+ # String işlemleri için önce string'e dönüştür
1571
+ if not isinstance(s, str):
1572
+ s = str(s)
1573
+
1185
1574
  s = s.strip()
1186
1575
  parts = [p.strip() for p in s.split(',')]
1187
1576
 
@@ -1197,7 +1586,25 @@ def _parse_splitcomplex(s: str) -> SplitcomplexNumber:
1197
1586
  pass
1198
1587
 
1199
1588
  raise ValueError(f"Geçersiz Split-Complex sayı formatı: '{s}' (Real, Split veya sadece Real bekleniyor)")
1589
+ """
1590
+ def _parse_splitcomplex(s: str) -> SplitcomplexNumber:
1591
+ #Virgülle ayrılmış string'i SplitcomplexNumber'a dönüştürür.
1592
+ s = s.strip()
1593
+ parts = [p.strip() for p in s.split(',')]
1200
1594
 
1595
+ if len(parts) == 2:
1596
+ try:
1597
+ return SplitcomplexNumber(float(parts[0]), float(parts[1]))
1598
+ except ValueError:
1599
+ pass
1600
+ elif len(parts) == 1: # Sadece real kısım verilmiş
1601
+ try:
1602
+ return SplitcomplexNumber(float(parts[0]), 0.0)
1603
+ except ValueError:
1604
+ pass
1605
+
1606
+ raise ValueError(f"Geçersiz Split-Complex sayı formatı: '{s}' (Real, Split veya sadece Real bekleniyor)")
1607
+ """
1201
1608
 
1202
1609
  class Constants:
1203
1610
  """Oktonyon sabitleri."""
@@ -2487,8 +2894,8 @@ def get_interactive() -> Tuple[List[Any], Dict[str, Any]]:
2487
2894
  9: "Enter Hyperreal start (in 'finite,infinitesimal' format, e.g., '0.0,0.0001'): ",
2488
2895
  10: "Enter Bicomplex start (in 'z1_real,z1_imag,z2_real,z2_imag' format, e.g., '1.0,2.0,3.0,4.0', '1.0,2.0', '3.0', '1.0+1.0j'): ",
2489
2896
  11: "Enter Neutro-Bicomplex start (in 'r,i,nr,ni,jr,ji,jnr,jni' format, e.g., '1,2,0.1,0.2,0.3,0.4,0.5,0.6', '0.1'): ",
2490
- 12: "Enter Octonion start (in 'e0,e1,e2,e3,e4,e5,e6,e7' format, e.g., '1.0,0.5,-0.2,0.3,0.1,-0.4,0.2,0.0'): ",
2491
- 13: "Enter Sedenion start (in 'e0,e1,...,e15' format, e.g., '1.0', '0.0'): ",
2897
+ 12: "Enter Octonion start (in 'w,x,y,z,e,f,g,h':'e0,e1,e2,e3,e4,e5,e6,e7' format, e.g., '1.0,0.5,-0.2,0.3,0.1,-0.4,0.2,0.0'): ",
2898
+ 13: "Enter Sedenion start (in 'e0,e1,...,e15' format, e.g., '1.0,2.0,3.0,0,0,0,0,0,0,0,0,0,0,0,0,0', '0.0'): ",
2492
2899
  14: "Enter Clifford start (in 'scalar,e1,e2,e12,...' format, e.g., '0.1+0.2e1', '1.0+2.0e1+3.0e12'): ",
2493
2900
  15: "Enter Dual start (in 'real,dual' format, e.g., '2.0,0.5'): ",
2494
2901
  16: "Enter Split-Complex start (in 'real,split' format, e.g., '1.0,0.8'): ",
@@ -2507,8 +2914,8 @@ def get_interactive() -> Tuple[List[Any], Dict[str, Any]]:
2507
2914
  9: "Enter Hyperreal increment (in 'finite,infinitesimal' format, e.g., '0.0,0.0001'): ",
2508
2915
  10: "Enter Bicomplex increment (in 'z1_real,z1_imag,z2_real,z2_imag' format, e.g., '1.0,2.0,3.0,4.0', '1.0,2.0', '3.0', '1.0+1.0j'): ",
2509
2916
  11: "Enter Neutro-Bicomplex increment (in 'r,i,nr,ni,jr,ji,jnr,jni' format, e.g., '1,2,0.1,0.2,0.3,0.4,0.5,0.6', '0.1')): ",
2510
- 12: "Enter Octonion increment (in 'e0,e1,e2,e3,e4,e5,e6,e7' format, e.g., '0.1', '0.0'): ",
2511
- 13: "Enter Sedenion increment (in 'e0,e1,...,e15' format, e.g., '0.1', '0.0'): ",
2917
+ 12: "Enter Octonion increment (in 'w,x,y,z,e,f,g,h':'e0,e1,e2,e3,e4,e5,e6,e7' format, e.g., '1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0', '0.0'): ",
2918
+ 13: "Enter Sedenion increment (in 'e0,e1,...,e15' format, e.g., '1.0,2.0,3.0,0,0,0,0,0,0,0,0,0,0,0,0,0', '0.0'): ",
2512
2919
  14: "Enter Clifford increment (in 'scalar,e1,e2,e12,...' format, e.g., '0.1+0.2e1', '1.0+2.0e1+3.0e12'): ",
2513
2920
  15: "Enter Dual increment (in 'real,dual' format, e.g., 1.0, '0.1,0.0'): ",
2514
2921
  16: "Enter Split-Complex increment (in 'real,split' format, e.g., '0.1,0.0'): ",
@@ -2620,6 +3027,13 @@ def plot_numbers(sequence: List[Any], title: str = "Keçeci Number Sequence Anal
2620
3027
  print("Sequence is empty. Nothing to plot.")
2621
3028
  return
2622
3029
 
3030
+ try:
3031
+ from sklearn.decomposition import PCA
3032
+ use_pca = True
3033
+ except ImportError:
3034
+ use_pca = False
3035
+ print("scikit-learn kurulu değil. PCA olmadan çizim yapılıyor...")
3036
+
2623
3037
  fig = plt.figure(figsize=(18, 14), constrained_layout=True)
2624
3038
  fig.suptitle(title, fontsize=18, fontweight='bold')
2625
3039
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececinumbers
3
- Version: 0.6.8
3
+ Version: 0.7.0
4
4
  Summary: Keçeci Numbers: An Exploration of a Dynamic Sequence Across Diverse Number Sets
5
5
  Home-page: https://github.com/WhiteSymmetry/kececinumbers
6
6
  Author: Mehmet Keçeci
@@ -136,7 +136,7 @@ Dynamic: requires-python
136
136
 
137
137
  **Keçeci Numbers** is a Python library for generating, analyzing, and visualizing dynamic sequences inspired by the Collatz Conjecture across diverse number systems.
138
138
 
139
- This library provides a unified algorithm that operates on 11 different number types, from standard integers to complex algebraic structures like quaternions and neutrosophic numbers. It is designed as a tool for academic research and exploration in number theory.
139
+ This library provides a unified algorithm that operates on 16 different number types, from standard integers to complex algebraic structures like quaternions and neutrosophic numbers. It is designed as a tool for academic research and exploration in number theory.
140
140
 
141
141
  <details>
142
142
  <summary>🇹🇷 Türkçe Açıklama (Click to expand)</summary>
@@ -160,11 +160,50 @@ This flexible mechanism provides a rich framework for studying the behavior of n
160
160
 
161
161
  ## Key Features
162
162
 
163
- * **11 Different Number Types:** Supports integers, rationals, complex numbers, quaternions, neutrosophic numbers, and more.
163
+ * **16 Different Number Types:** Supports integers, rationals, complex numbers, quaternions, neutrosophic numbers, and more.
164
164
  * **Unified Generator:** Uses a single, consistent `unified_generator` algorithm for all number types.
165
165
  * **Advanced Visualization:** Provides a multi-dimensional `plot_numbers` function tailored to the nature of each number system.
166
166
  * **Keçeci Prime Number (KPN) Analysis:** Identifies the most recurring prime representation in sequences to analyze their convergence behavior.
167
167
  * **Interactive and Programmatic Usage:** Supports both interactive parameter input (`get_interactive`) and direct use in scripts (`get_with_params`).
168
+ * 0.6.9: 16 Numbers
169
+ * 0.6.7: 11 Numbers
170
+
171
+ ---
172
+
173
+ ## MODULE CONSTANTS: KEÇECİ NUMBER TYPES
174
+
175
+
176
+ TYPE_POSITIVE_REAL = 1
177
+
178
+ TYPE_NEGATIVE_REAL = 2
179
+
180
+ TYPE_COMPLEX = 3
181
+
182
+ TYPE_FLOAT = 4
183
+
184
+ TYPE_RATIONAL = 5
185
+
186
+ TYPE_QUATERNION = 6
187
+
188
+ TYPE_NEUTROSOPHIC = 7
189
+
190
+ TYPE_NEUTROSOPHIC_COMPLEX = 8
191
+
192
+ TYPE_HYPERREAL = 9
193
+
194
+ TYPE_BICOMPLEX = 10
195
+
196
+ TYPE_NEUTROSOPHIC_BICOMPLEX = 11
197
+
198
+ TYPE_OCTONION = 12
199
+
200
+ TYPE_SEDENION = 13
201
+
202
+ TYPE_CLIFFORD = 14
203
+
204
+ TYPE_DUAL = 15
205
+
206
+ TYPE_SPLIT_COMPLEX = 16
168
207
 
169
208
  ---
170
209
 
@@ -410,7 +449,18 @@ Keçeci Number Types:
410
449
 
411
450
  11: Neutro-Bicomplex
412
451
 
413
- Please select Keçeci Number Type (1-11): 1
452
+ 12: Octonion (in 'e0,e1,e2,e3,e4,e5,e6,e7' format, e.g., '1.0,0.5,-0.2,0.3,0.1,-0.4,0.2,0.0')
453
+
454
+ 13: "Sedenion(in 'e0,e1,...,e15' format, e.g., '1.0', '0.0'): ",
455
+
456
+ 14: "Clifford(in 'scalar,e1,e2,e12,...' format, e.g., '0.1+0.2e1', '1.0+2.0e1+3.0e12')
457
+
458
+ 15: "Dual(in 'real,dual' format, e.g., '2.0,0.5')
459
+
460
+ 16: "Split-Complex(in 'real,split' format, e.g., '1.0,0.8')
461
+
462
+
463
+ Please select Keçeci Number Type (1-16): 1
414
464
 
415
465
  Enter the starting number (e.g., 0 or 2.5, complex:3+4j, rational: 3/4, quaternions: 1) : 0
416
466
 
@@ -0,0 +1,10 @@
1
+ docs/conf.py,sha256=jkpH_TchRJcC_EspKeY1E_rml2ODmIWhWoqvyCPu_ok,1116
2
+ kececinumbers/__init__.py,sha256=xH57meQp1_XJkvhPk0xhcWY4JDdjJqczGZyquQp3FhU,8399
3
+ kececinumbers/_version.py,sha256=IsAwgEBGv0MCYhqJB1-8JcWqXvpe5XS3aoGM-R-nIjA,453
4
+ kececinumbers/kececinumbers.py,sha256=ZpYyo8TETrUJHoRmYnu2TKFc68NBzAcSpaZn83_SoCw,139756
5
+ kececinumbers-0.7.0.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
6
+ tests/test_sample.py,sha256=vwGbEZ6gcEFq60P5Sqrnc_DVw2QFXOSU1vm3GyzQMnc,9628
7
+ kececinumbers-0.7.0.dist-info/METADATA,sha256=TdCKhEYrttkHoujp12aH2W0F2Esf_V4OSJ8UBnyKdgU,34887
8
+ kececinumbers-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ kececinumbers-0.7.0.dist-info/top_level.txt,sha256=ABQEKRH9iYb4sWnFdx7gIx7Hg899YktRkQpbRlSSqwU,25
10
+ kececinumbers-0.7.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- docs/conf.py,sha256=jkpH_TchRJcC_EspKeY1E_rml2ODmIWhWoqvyCPu_ok,1116
2
- kececinumbers/__init__.py,sha256=4bsoC1-VftHH6p9ZP21HTlmvOjqxV3HlFsovoHPXCis,8399
3
- kececinumbers/_version.py,sha256=fqu2lHgewipDERoAgq-2zYXbVPijC9JsV1p3Xuw5oSI,453
4
- kececinumbers/kececinumbers.py,sha256=5rITANhxL8poHTu4beOvhLaBPXEDSHDIOo_d6-mWUcE,125127
5
- kececinumbers-0.6.8.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
6
- tests/test_sample.py,sha256=vwGbEZ6gcEFq60P5Sqrnc_DVw2QFXOSU1vm3GyzQMnc,9628
7
- kececinumbers-0.6.8.dist-info/METADATA,sha256=Cz8Lp7D871IDV_m_edM1XdHtOfHvg8dJ3zQuZvxU9JU,34047
8
- kececinumbers-0.6.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- kececinumbers-0.6.8.dist-info/top_level.txt,sha256=ABQEKRH9iYb4sWnFdx7gIx7Hg899YktRkQpbRlSSqwU,25
10
- kececinumbers-0.6.8.dist-info/RECORD,,