kececinumbers 0.3.3__py3-none-any.whl → 0.3.5__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.
@@ -1,5 +1,3 @@
1
- ### `kececinumbers.py`
2
-
3
1
  # -*- coding: utf-8 -*-
4
2
  """
5
3
  Keçeci Numbers Module (kececinumbers.py)
@@ -19,8 +17,8 @@ Key Features:
19
17
  - Helper functions for mathematical properties like primality and divisibility.
20
18
  - Advanced plotting capabilities tailored to each number system.
21
19
  - Functions for interactive use or programmatic integration.
22
- """
23
- """
20
+ ---
21
+
24
22
  Keçeci Conjecture: Keçeci Varsayımı, Keçeci-Vermutung, Conjecture de Keçeci, Гипотеза Кечеджи, 凯杰西猜想, ケジェジ予想, Keçeci Huds, Keçeci Hudsiye, Keçeci Hudsia, كَچَه جِي ,حدس کچه جی, کچہ جی حدسیہ
25
23
 
26
24
  Keçeci Varsayımı (Keçeci Conjecture) - Önerilen
@@ -28,28 +26,21 @@ Keçeci Varsayımı (Keçeci Conjecture) - Önerilen
28
26
  Her Keçeci Sayı türü için, `unified_generator` fonksiyonu tarafından oluşturulan dizilerin, sonlu adımdan sonra periyodik bir yapıya veya tekrar eden bir asal temsiline (Keçeci Asal Sayısı, KPN) yakınsadığı sanılmaktadır. Bu davranış, Collatz Varsayımı'nın çoklu cebirsel sistemlere genişletilmiş bir hali olarak değerlendirilebilir.
29
27
 
30
28
  Henüz kanıtlanmamıştır ve bu modül bu varsayımı test etmek için bir çerçeve sunar.
31
-
32
- # Keçeci Conjecture - Proposed
33
-
34
- For every Keçeci Number type, sequences generated by the `unified_generator` function are conjectured to converge to a periodic structure or a recurring prime representation (Keçeci Prime Number, KPN) in finitely many steps. This behavior can be viewed as a generalization of the Collatz Conjecture to multiple algebraic systems.
35
-
36
- It remains unproven, and this module provides a framework for testing the conjecture.
37
-
38
29
  """
39
30
 
40
31
  # --- Standard Library Imports ---
41
32
  import collections
42
- import math
43
- import random
44
33
  from dataclasses import dataclass
45
34
  from fractions import Fraction
46
-
47
- # --- Third-Party Imports ---
35
+ import math
36
+ from matplotlib.gridspec import GridSpec
48
37
  import matplotlib.pyplot as plt
49
38
  import numpy as np
50
- import quaternion # Requires: pip install numpy numpy-quaternion
51
- from matplotlib.gridspec import GridSpec
39
+ import quaternion
40
+ import random
52
41
  import re
42
+ from typing import Any, Dict, List, Optional, Tuple
43
+
53
44
 
54
45
  # ==============================================================================
55
46
  # --- MODULE CONSTANTS: KEÇECI NUMBER TYPES ---
@@ -72,300 +63,187 @@ TYPE_NEUTROSOPHIC_BICOMPLEX = 11
72
63
 
73
64
  @dataclass
74
65
  class NeutrosophicNumber:
75
- """
76
- Represents a neutrosophic number of the form a + bI, where I is the
77
- indeterminate part and I^2 = I.
78
-
79
- Attributes:
80
- a (float): The determinate part.
81
- b (float): The indeterminate part.
82
- """
66
+ """Represents a neutrosophic number of the form a + bI where I^2 = I."""
83
67
  a: float
84
68
  b: float
85
69
 
86
- def __add__(self, other):
70
+ def __add__(self, other: Any) -> "NeutrosophicNumber":
87
71
  if isinstance(other, NeutrosophicNumber):
88
72
  return NeutrosophicNumber(self.a + other.a, self.b + other.b)
89
- return NeutrosophicNumber(self.a + other, self.b)
73
+ if isinstance(other, (int, float)):
74
+ return NeutrosophicNumber(self.a + other, self.b)
75
+ return NotImplemented
90
76
 
91
- def __sub__(self, other):
77
+ def __sub__(self, other: Any) -> "NeutrosophicNumber":
92
78
  if isinstance(other, NeutrosophicNumber):
93
79
  return NeutrosophicNumber(self.a - other.a, self.b - other.b)
94
- return NeutrosophicNumber(self.a - other, self.b)
80
+ if isinstance(other, (int, float)):
81
+ return NeutrosophicNumber(self.a - other, self.b)
82
+ return NotImplemented
95
83
 
96
- def __mul__(self, other):
84
+ def __mul__(self, other: Any) -> "NeutrosophicNumber":
97
85
  if isinstance(other, NeutrosophicNumber):
98
- # (a + bI)(c + dI) = ac + (ad + bc + bd)I
99
86
  return NeutrosophicNumber(
100
87
  self.a * other.a,
101
- self.a * other.b + self.b * other.a + self.b * other.b
88
+ self.a * other.b + self.b * other.a + self.b * other.b,
102
89
  )
103
- return NeutrosophicNumber(self.a * other, self.b * other)
90
+ if isinstance(other, (int, float)):
91
+ return NeutrosophicNumber(self.a * other, self.b * other)
92
+ return NotImplemented
104
93
 
105
- def __truediv__(self, divisor):
94
+ def __truediv__(self, divisor: float) -> "NeutrosophicNumber":
106
95
  if isinstance(divisor, (int, float)):
96
+ if divisor == 0:
97
+ raise ZeroDivisionError("Cannot divide by zero.")
107
98
  return NeutrosophicNumber(self.a / divisor, self.b / divisor)
108
- raise TypeError("Only scalar division is supported for NeutrosophicNumber.")
99
+ raise TypeError("Only scalar division is supported.")
109
100
 
110
- def __str__(self):
101
+ def __str__(self) -> str:
111
102
  return f"{self.a} + {self.b}I"
112
103
 
113
104
  @dataclass
114
105
  class NeutrosophicComplexNumber:
115
- """
116
- Represents a neutrosophic-complex number, combining a standard complex number
117
- (real + imag*j) with an independent level of indeterminacy (I).
118
-
119
- This object models systems where a value has both a complex-valued state
120
- (like quantum amplitude) and an associated level of uncertainty or
121
- unreliability (like quantum decoherence).
122
-
123
- Attributes:
124
- real (float): The real part of the deterministic component.
125
- imag (float): The imaginary part of the deterministic component.
126
- indeterminacy (float): The coefficient of the indeterminate part, I.
127
- """
128
-
129
- def __init__(self, real: float = 0.0, imag: float = 0.0, indeterminacy: float = 0.0):
130
- """
131
- Initialises a NeutrosophicComplexNumber.
132
-
133
- Args:
134
- real (float): The initial real part. Defaults to 0.0.
135
- imag (float): The initial imaginary part. Defaults to 0.0.
136
- indeterminacy (float): The initial indeterminacy level. Defaults to 0.0.
137
- """
138
- self.real = float(real)
139
- self.imag = float(imag)
140
- self.indeterminacy = float(indeterminacy)
106
+ """Represents a number with a complex part and an indeterminacy level."""
107
+ real: float = 0.0
108
+ imag: float = 0.0
109
+ indeterminacy: float = 0.0
141
110
 
142
111
  def __repr__(self) -> str:
143
- """
144
- Returns an unambiguous, developer-friendly representation of the object.
145
- """
146
112
  return f"NeutrosophicComplexNumber(real={self.real}, imag={self.imag}, indeterminacy={self.indeterminacy})"
147
113
 
148
114
  def __str__(self) -> str:
149
- """
150
- Returns a user-friendly string representation of the object.
151
- """
152
- # Shows a sign for the imaginary part for clarity (e.g., +1.0j, -2.0j)
153
115
  return f"({self.real}{self.imag:+}j) + {self.indeterminacy}I"
154
116
 
155
- # --- Mathematical Operations ---
156
-
157
- def __add__(self, other):
158
- """Adds another number to this one."""
117
+ def __add__(self, other: Any) -> "NeutrosophicComplexNumber":
159
118
  if isinstance(other, NeutrosophicComplexNumber):
160
119
  return NeutrosophicComplexNumber(
161
- self.real + other.real,
162
- self.imag + other.imag,
163
- self.indeterminacy + other.indeterminacy
120
+ self.real + other.real, self.imag + other.imag, self.indeterminacy + other.indeterminacy
164
121
  )
165
- # Allows adding a scalar (int/float) to the real part.
166
- elif isinstance(other, (int, float)):
122
+ if isinstance(other, (int, float)):
167
123
  return NeutrosophicComplexNumber(self.real + other, self.imag, self.indeterminacy)
168
124
  return NotImplemented
169
125
 
170
- def __sub__(self, other):
171
- """Subtracts another number from this one."""
126
+ def __sub__(self, other: Any) -> "NeutrosophicComplexNumber":
172
127
  if isinstance(other, NeutrosophicComplexNumber):
173
128
  return NeutrosophicComplexNumber(
174
- self.real - other.real,
175
- self.imag - other.imag,
176
- self.indeterminacy - other.indeterminacy
129
+ self.real - other.real, self.imag - other.imag, self.indeterminacy - other.indeterminacy
177
130
  )
178
- elif isinstance(other, (int, float)):
179
- return NeutrosophicComplexNumber(self.real - other, self.imag, self.indeterminacy)
131
+ if isinstance(other, (int, float)):
132
+ return NeutrosophicComplexNumber(self.real - other, self.imag, self.indeterminacy)
180
133
  return NotImplemented
181
134
 
182
- def __mul__(self, other):
183
- """
184
- Multiplies this number by another number (scalar, complex, or neutrosophic-complex).
185
- This is the most critical operation for complex dynamics.
186
- """
135
+ def __mul__(self, other: Any) -> "NeutrosophicComplexNumber":
187
136
  if isinstance(other, NeutrosophicComplexNumber):
188
- # (a+bj)*(c+dj) = (ac-bd) + (ad+bc)j
189
137
  new_real = self.real * other.real - self.imag * other.imag
190
138
  new_imag = self.real * other.imag + self.imag * other.real
191
-
192
- # The indeterminacy grows based on both original indeterminacies and
193
- # the magnitude of the deterministic part, creating rich, non-linear behaviour.
194
139
  new_indeterminacy = self.indeterminacy + other.indeterminacy + (self.magnitude_sq() * other.indeterminacy)
195
-
196
140
  return NeutrosophicComplexNumber(new_real, new_imag, new_indeterminacy)
197
-
198
- elif isinstance(other, complex):
199
- # Multiply by a standard Python complex number
141
+ if isinstance(other, complex):
200
142
  new_real = self.real * other.real - self.imag * other.imag
201
143
  new_imag = self.real * other.imag + self.imag * other.real
202
- # The indeterminacy is unaffected when multiplied by a purely deterministic complex number.
203
144
  return NeutrosophicComplexNumber(new_real, new_imag, self.indeterminacy)
204
-
205
- elif isinstance(other, (int, float)):
206
- # Multiply by a scalar
207
- return NeutrosophicComplexNumber(
208
- self.real * other,
209
- self.imag * other,
210
- self.indeterminacy * other
211
- )
145
+ if isinstance(other, (int, float)):
146
+ return NeutrosophicComplexNumber(self.real * other, self.imag * other, self.indeterminacy * other)
212
147
  return NotImplemented
213
148
 
214
- def __truediv__(self, divisor):
215
- """Divides this number by a scalar."""
149
+ def __truediv__(self, divisor: float) -> "NeutrosophicComplexNumber":
216
150
  if isinstance(divisor, (int, float)):
217
151
  if divisor == 0:
218
- raise ZeroDivisionError("Cannot divide a NeutrosophicComplexNumber by zero.")
152
+ raise ZeroDivisionError("Cannot divide by zero.")
219
153
  return NeutrosophicComplexNumber(
220
- self.real / divisor,
221
- self.imag / divisor,
222
- self.indeterminacy / divisor
154
+ self.real / divisor, self.imag / divisor, self.indeterminacy / divisor
223
155
  )
224
- raise TypeError("Only scalar division is supported for NeutrosophicComplexNumber.")
225
-
226
- # --- Reversed Mathematical Operations ---
156
+ raise TypeError("Only scalar division is supported.")
227
157
 
228
- def __radd__(self, other):
229
- """Handles cases like `5 + my_number`."""
158
+ def __radd__(self, other: Any) -> "NeutrosophicComplexNumber":
230
159
  return self.__add__(other)
231
160
 
232
- def __rsub__(self, other):
233
- """Handles cases like `5 - my_number`."""
161
+ def __rsub__(self, other: Any) -> "NeutrosophicComplexNumber":
234
162
  if isinstance(other, (int, float)):
235
163
  return NeutrosophicComplexNumber(other - self.real, -self.imag, -self.indeterminacy)
236
164
  return NotImplemented
237
165
 
238
- def __rmul__(self, other):
239
- """Handles cases like `5 * my_number`."""
166
+ def __rmul__(self, other: Any) -> "NeutrosophicComplexNumber":
240
167
  return self.__mul__(other)
241
168
 
242
- # --- Unary and Comparison Operations ---
243
-
244
- def __neg__(self):
245
- """Returns the negative of the number."""
246
- return NeutrosophicComplexNumber(-self.real, -self.imag, self.indeterminacy)
247
-
248
- def __eq__(self, other) -> bool:
249
- """Checks for equality between two numbers."""
250
- if not isinstance(other, NeutrosophicComplexNumber):
251
- return False
252
- return (self.real == other.real and
253
- self.imag == other.imag and
254
- self.indeterminacy == other.indeterminacy)
255
-
256
- # --- Helper Methods ---
257
-
258
169
  def magnitude_sq(self) -> float:
259
- """Returns the squared magnitude of the deterministic (complex) part."""
260
170
  return self.real**2 + self.imag**2
261
171
 
262
- def magnitude(self) -> float:
263
- """Returns the magnitude (modulus or absolute value) of the deterministic part."""
264
- return math.sqrt(self.magnitude_sq())
265
-
266
- def deterministic_part(self) -> complex:
267
- """Returns the deterministic part as a standard Python complex number."""
268
- return complex(self.real, self.imag)
269
-
270
-
271
172
  @dataclass
272
173
  class HyperrealNumber:
273
- """
274
- Represents a hyperreal number as a sequence of real numbers.
275
- Operations are performed element-wise on the sequences.
276
-
277
- Attributes:
278
- sequence (list[float]): The sequence representing the hyperreal.
279
- """
174
+ """Represents a hyperreal number as a sequence of real numbers."""
280
175
  sequence: list
281
176
 
282
- def __add__(self, other):
177
+ def __add__(self, other: Any) -> "HyperrealNumber":
283
178
  if isinstance(other, HyperrealNumber):
284
179
  return HyperrealNumber([a + b for a, b in zip(self.sequence, other.sequence)])
285
- raise TypeError("Unsupported operand for +: HyperrealNumber and non-HyperrealNumber.")
286
-
287
- def __sub__(self, other):
180
+ return NotImplemented
181
+
182
+ def __sub__(self, other: Any) -> "HyperrealNumber":
288
183
  if isinstance(other, HyperrealNumber):
289
184
  return HyperrealNumber([a - b for a, b in zip(self.sequence, other.sequence)])
290
- raise TypeError("Unsupported operand for -: HyperrealNumber and non-HyperrealNumber.")
185
+ return NotImplemented
291
186
 
292
- # --- YENİ EKLENEN DÜZELTME ---
293
- # --- NEWLY ADDED FIX ---
294
- def __mul__(self, scalar):
295
- """Handles multiplication by a scalar (int or float)."""
187
+ def __mul__(self, scalar: float) -> "HyperrealNumber":
296
188
  if isinstance(scalar, (int, float)):
297
189
  return HyperrealNumber([x * scalar for x in self.sequence])
298
- raise TypeError(f"Unsupported operand for *: HyperrealNumber and {type(scalar).__name__}")
299
-
300
- def __rmul__(self, scalar):
301
- """Handles the case where the scalar is on the left (e.g., float * HyperrealNumber)."""
190
+ return NotImplemented
191
+
192
+ def __rmul__(self, scalar: float) -> "HyperrealNumber":
302
193
  return self.__mul__(scalar)
303
- # --- DÜZELTME SONU ---
304
- # --- END OF FIX ---
305
194
 
306
- def __truediv__(self, divisor):
195
+ def __truediv__(self, divisor: float) -> "HyperrealNumber":
307
196
  if isinstance(divisor, (int, float)):
308
197
  if divisor == 0:
309
198
  raise ZeroDivisionError("Scalar division by zero.")
310
199
  return HyperrealNumber([x / divisor for x in self.sequence])
311
200
  raise TypeError("Only scalar division is supported.")
312
-
313
- def __mod__(self, divisor):
201
+
202
+ def __mod__(self, divisor: float) -> List[float]:
314
203
  if isinstance(divisor, (int, float)):
315
204
  return [x % divisor for x in self.sequence]
316
- raise TypeError("Modulo operation only supported with a scalar divisor.")
205
+ raise TypeError("Modulo only supported with a scalar divisor.")
317
206
 
318
- def __str__(self):
207
+ def __str__(self) -> str:
319
208
  return f"Hyperreal({self.sequence[:3]}...)"
320
209
 
321
210
  @dataclass
322
211
  class BicomplexNumber:
323
- """
324
- Represents a bicomplex number of the form z1 + j*z2, where z1 and z2
325
- are standard complex numbers, i^2 = -1, and j^2 = -1.
326
-
327
- Attributes:
328
- z1 (complex): The first complex component.
329
- z2 (complex): The second complex component (coefficient of j).
330
- """
212
+ """Represents a bicomplex number z1 + j*z2, where i^2 = j^2 = -1."""
331
213
  z1: complex
332
214
  z2: complex
333
-
334
- def __add__(self, other):
215
+
216
+ def __add__(self, other: Any) -> "BicomplexNumber":
335
217
  if isinstance(other, BicomplexNumber):
336
218
  return BicomplexNumber(self.z1 + other.z1, self.z2 + other.z2)
337
- raise TypeError("Unsupported operand for +: BicomplexNumber and non-BicomplexNumber.")
219
+ return NotImplemented
338
220
 
339
- def __sub__(self, other):
221
+ def __sub__(self, other: Any) -> "BicomplexNumber":
340
222
  if isinstance(other, BicomplexNumber):
341
223
  return BicomplexNumber(self.z1 - other.z1, self.z2 - other.z2)
342
- raise TypeError("Unsupported operand for -: BicomplexNumber and non-BicomplexNumber.")
224
+ return NotImplemented
343
225
 
344
- def __mul__(self, other):
226
+ def __mul__(self, other: Any) -> "BicomplexNumber":
345
227
  if isinstance(other, BicomplexNumber):
346
- # (z1 + z2j)(w1 + w2j) = (z1w1 - z2w2) + (z1w2 + z2w1)j
347
228
  return BicomplexNumber(
348
229
  (self.z1 * other.z1) - (self.z2 * other.z2),
349
- (self.z1 * other.z2) + (self.z2 * other.z1)
230
+ (self.z1 * other.z2) + (self.z2 * other.z1),
350
231
  )
351
- raise TypeError("Unsupported operand for *: BicomplexNumber and non-BicomplexNumber.")
352
-
353
- def __truediv__(self, scalar):
232
+ return NotImplemented
233
+
234
+ def __truediv__(self, scalar: float) -> "BicomplexNumber":
354
235
  if isinstance(scalar, (int, float)):
236
+ if scalar == 0:
237
+ raise ZeroDivisionError("Cannot divide by zero.")
355
238
  return BicomplexNumber(self.z1 / scalar, self.z2 / scalar)
356
239
  raise TypeError("Only scalar division is supported.")
357
240
 
358
- def __str__(self):
241
+ def __str__(self) -> str:
359
242
  return f"Bicomplex({self.z1}, {self.z2})"
360
243
 
361
244
  @dataclass
362
245
  class NeutrosophicBicomplexNumber:
363
- """
364
- Represents a highly complex number with multiple components.
365
- NOTE: The multiplication implemented here is a simplified, element-wise
366
- operation for demonstrative purposes and is not mathematically rigorous.
367
- The true algebraic multiplication is exceedingly complex.
368
- """
246
+ """Represents a simplified neutrosophic-bicomplex number."""
369
247
  real: float
370
248
  imag: float
371
249
  neut_real: float
@@ -375,252 +253,187 @@ class NeutrosophicBicomplexNumber:
375
253
  j_neut_real: float
376
254
  j_neut_imag: float
377
255
 
378
- def __add__(self, other):
256
+ def __add__(self, other: Any) -> "NeutrosophicBicomplexNumber":
379
257
  if isinstance(other, NeutrosophicBicomplexNumber):
380
258
  return NeutrosophicBicomplexNumber(*(a + b for a, b in zip(self.__dict__.values(), other.__dict__.values())))
381
- raise TypeError("Unsupported operand for +.")
382
-
383
- def __sub__(self, other):
259
+ return NotImplemented
260
+
261
+ def __sub__(self, other: Any) -> "NeutrosophicBicomplexNumber":
384
262
  if isinstance(other, NeutrosophicBicomplexNumber):
385
263
  return NeutrosophicBicomplexNumber(*(a - b for a, b in zip(self.__dict__.values(), other.__dict__.values())))
386
- raise TypeError("Unsupported operand for -.")
387
-
388
- def __truediv__(self, scalar):
264
+ return NotImplemented
265
+
266
+ def __truediv__(self, scalar: float) -> "NeutrosophicBicomplexNumber":
389
267
  if isinstance(scalar, (int, float)):
268
+ if scalar == 0:
269
+ raise ZeroDivisionError("Cannot divide by zero.")
390
270
  return NeutrosophicBicomplexNumber(*(val / scalar for val in self.__dict__.values()))
391
271
  raise TypeError("Only scalar division supported.")
392
272
 
393
- def __str__(self):
273
+ def __str__(self) -> str:
394
274
  return f"NeutroBicomplex(r={self.real}, i={self.imag}, Ir={self.neut_real}, ...)"
395
275
 
396
-
397
276
  # ==============================================================================
398
277
  # --- HELPER FUNCTIONS ---
399
278
  # ==============================================================================
400
279
 
401
- def is_prime(n_input):
402
- """
403
- Checks if a given number (or its principal component) is prime.
404
- Extracts the relevant integer part from various number types for testing.
405
- """
406
- value_to_check = 0
407
- # Extract the integer part to check for primality based on type
408
- if isinstance(n_input, (int, float)):
409
- value_to_check = abs(int(n_input))
410
- elif isinstance(n_input, Fraction):
411
- value_to_check = abs(int(n_input))
412
- elif isinstance(n_input, complex):
413
- value_to_check = abs(int(n_input.real))
414
- elif isinstance(n_input, np.quaternion):
415
- value_to_check = abs(int(n_input.w))
416
- elif isinstance(n_input, NeutrosophicNumber):
417
- value_to_check = abs(int(n_input.a))
418
- elif isinstance(n_input, NeutrosophicComplexNumber):
419
- value_to_check = abs(int(n_input.real))
420
- elif isinstance(n_input, HyperrealNumber):
421
- value_to_check = abs(int(n_input.sequence[0])) if n_input.sequence else 0
422
- elif isinstance(n_input, BicomplexNumber):
423
- value_to_check = abs(int(n_input.z1.real))
424
- elif isinstance(n_input, NeutrosophicBicomplexNumber):
425
- value_to_check = abs(int(n_input.real))
426
- else:
427
- try:
428
- value_to_check = abs(int(n_input))
429
- except (ValueError, TypeError):
430
- return False
280
+ def _get_integer_representation(n_input: Any) -> Optional[int]:
281
+ """Extracts the primary integer component from any supported number type."""
282
+ try:
283
+ if isinstance(n_input, (int, float, Fraction)):
284
+ return abs(int(n_input))
285
+ if isinstance(n_input, complex):
286
+ return abs(int(n_input.real))
287
+ if isinstance(n_input, np.quaternion):
288
+ return abs(int(n_input.w))
289
+ if isinstance(n_input, NeutrosophicNumber):
290
+ return abs(int(n_input.a))
291
+ if isinstance(n_input, NeutrosophicComplexNumber):
292
+ return abs(int(n_input.real))
293
+ if isinstance(n_input, HyperrealNumber):
294
+ return abs(int(n_input.sequence[0])) if n_input.sequence else 0
295
+ if isinstance(n_input, BicomplexNumber):
296
+ return abs(int(n_input.z1.real))
297
+ if isinstance(n_input, NeutrosophicBicomplexNumber):
298
+ return abs(int(n_input.real))
299
+ return abs(int(n_input))
300
+ except (ValueError, TypeError, IndexError):
301
+ return None
431
302
 
432
- # Standard primality test algorithm
433
- if value_to_check < 2:
303
+ def is_prime(n_input: Any) -> bool:
304
+ """Checks if a given number (or its principal component) is prime."""
305
+ value_to_check = _get_integer_representation(n_input)
306
+ if value_to_check is None or value_to_check < 2:
434
307
  return False
435
308
  if value_to_check == 2:
436
309
  return True
437
310
  if value_to_check % 2 == 0:
438
311
  return False
439
- # Check only odd divisors up to the square root
440
312
  for i in range(3, int(math.sqrt(value_to_check)) + 1, 2):
441
313
  if value_to_check % i == 0:
442
314
  return False
443
315
  return True
444
316
 
445
- def _is_divisible(value, divisor, kececi_type):
446
- """
447
- Helper to check divisibility for different number types.
448
- Returns True if a number is "perfectly divisible" by an integer divisor.
449
- """
317
+ def _is_divisible(value: Any, divisor: int, kececi_type: int) -> bool:
318
+ """Helper to check divisibility for different number types."""
450
319
  try:
451
320
  if kececi_type in [TYPE_POSITIVE_REAL, TYPE_NEGATIVE_REAL]:
452
321
  return value % divisor == 0
453
- elif kececi_type == TYPE_FLOAT:
322
+ if kececi_type == TYPE_FLOAT:
454
323
  return math.isclose(value % divisor, 0)
455
- elif kececi_type == TYPE_RATIONAL:
324
+ if kececi_type == TYPE_RATIONAL:
456
325
  return (value / divisor).denominator == 1
457
- elif kececi_type == TYPE_COMPLEX:
326
+ if kececi_type == TYPE_COMPLEX:
458
327
  return math.isclose(value.real % divisor, 0) and math.isclose(value.imag % divisor, 0)
459
- elif kececi_type == TYPE_QUATERNION:
328
+ if kececi_type == TYPE_QUATERNION:
460
329
  return all(math.isclose(c % divisor, 0) for c in [value.w, value.x, value.y, value.z])
461
- elif kececi_type == TYPE_NEUTROSOPHIC:
330
+ if kececi_type == TYPE_NEUTROSOPHIC:
462
331
  return math.isclose(value.a % divisor, 0) and math.isclose(value.b % divisor, 0)
463
- elif kececi_type == TYPE_NEUTROSOPHIC_COMPLEX:
332
+ if kececi_type == TYPE_NEUTROSOPHIC_COMPLEX:
464
333
  return all(math.isclose(c % divisor, 0) for c in [value.real, value.imag, value.indeterminacy])
465
- elif kececi_type == TYPE_HYPERREAL:
334
+ if kececi_type == TYPE_HYPERREAL:
466
335
  return all(math.isclose(x % divisor, 0) for x in value.sequence)
467
- elif kececi_type == TYPE_BICOMPLEX:
468
- return (_is_divisible(value.z1, divisor, TYPE_COMPLEX) and
469
- _is_divisible(value.z2, divisor, TYPE_COMPLEX))
470
- elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
336
+ if kececi_type == TYPE_BICOMPLEX:
337
+ return _is_divisible(value.z1, divisor, TYPE_COMPLEX) and _is_divisible(value.z2, divisor, TYPE_COMPLEX)
338
+ if kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
471
339
  return all(math.isclose(c % divisor, 0) for c in value.__dict__.values())
472
340
  except (TypeError, ValueError):
473
341
  return False
474
342
  return False
475
343
 
476
344
  def _parse_complex(s: str) -> complex:
477
- """
478
- Bir string'i kompleks sayıya çevirir.
479
- Eğer 'j' içermiyorsa, "3" girdisini 3+3j olarak yorumlar.
480
- """
345
+ """Parses a string into a complex number. '3' becomes 3+3j."""
481
346
  s_clean = s.strip().lower()
482
347
  try:
483
- # Doğrudan kompleks çevirmeyi dene (ör: "3+4j")
484
348
  c = complex(s_clean)
485
- # Eğer girdi "3" gibi sadece reel bir sayıysa ve 'j' içermiyorsa,
486
- # onu s_complex.real + s_complex.real*j yap.
487
349
  if c.imag == 0 and 'j' not in s_clean:
488
350
  return complex(c.real, c.real)
489
351
  return c
490
352
  except ValueError as e:
491
- raise ValueError(f"Geçersiz kompleks sayı formatı: '{s}'") from e
353
+ raise ValueError(f"Invalid complex number format: '{s}'") from e
492
354
 
493
- def _parse_neutrosophic(s: str) -> (float, float):
494
- """
495
- Parses a neutrosophic number string of the form 'a+bI' into a tuple (a, b).
496
- Handles cases like '5+2I', '3-I', '7', '4I', '-I'.
497
- """
355
+ def _parse_neutrosophic(s: str) -> Tuple[float, float]:
356
+ """Parses a neutrosophic string 'a+bI' into a tuple (a, b)."""
498
357
  s = s.strip().replace(" ", "").upper()
499
358
  if not s:
500
359
  return 0.0, 0.0
501
360
 
502
- # Eğer 'I' yoksa, bu standart bir sayıdır (b=0)
503
361
  if 'I' not in s:
504
- try:
505
- return float(s), 0.0
506
- except ValueError:
507
- raise ValueError(f"Invalid number format for non-neutrosophic part: {s}")
362
+ return float(s), 0.0
508
363
 
509
- # 'I' varsa, a ve b kısımlarını ayır
510
- # 'b' kısmını bul
511
- i_pos = s.find('I')
512
- a_part_str = s[:i_pos]
513
-
514
- # Sadece 'I' veya '-I' gibi durumlar
515
- if not a_part_str or a_part_str == '+':
516
- b = 1.0
517
- elif a_part_str == '-':
518
- b = -1.0
364
+ pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?)I$")
365
+ match = re.match(r"^(?P<val>[+-]?\d+\.?\d*)$", s)
366
+ if match: # Just a number
367
+ return float(match.group('val')), 0.0
368
+
369
+ pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)I$")
370
+ full_match = pattern.match(s)
371
+ if not full_match:
372
+ raise ValueError(f"Invalid neutrosophic format: {s}")
373
+
374
+ parts = full_match.groupdict()
375
+ a_part = parts.get('a') or "0"
376
+ b_part = parts.get('b')
377
+
378
+ if b_part in (None, "", "+"):
379
+ b_val = 1.0
380
+ elif b_part == "-":
381
+ b_val = -1.0
519
382
  else:
520
- # 'a' ve 'b' kısımlarını ayırmak için sondaki işareti bul
521
- last_plus = a_part_str.rfind('+')
522
- last_minus = a_part_str.rfind('-')
383
+ b_val = float(b_part)
523
384
 
524
- # Eğer başta eksi işareti varsa onu ayraç olarak sayma
525
- if last_minus == 0 and last_plus == -1:
526
- split_pos = -1
527
- else:
528
- split_pos = max(last_plus, last_minus)
529
-
530
- if split_pos == -1: # Örneğin '3I' durumu
531
- a = 0.0
532
- b = float(a_part_str)
533
- else: # Örneğin '5+3I' veya '-2-4I' durumu
534
- a = float(a_part_str[:split_pos])
535
- b_str = a_part_str[split_pos:]
536
- if b_str == '+':
537
- b = 1.0
538
- elif b_str == '-':
539
- b = -1.0
540
- else:
541
- b = float(b_str)
542
-
543
- return a, b
385
+ return float(a_part), b_val
544
386
 
545
- def _parse_hyperreal(s: str) -> (float, float):
546
- """
547
- 'a+be' formatındaki bir hiperreel string'i (a, b) demetine ayrıştırır.
548
- '5+3e', '-2-e', '10', '4e', '-e' gibi formatları işler.
549
- """
387
+
388
+ def _parse_hyperreal(s: str) -> Tuple[float, float]:
389
+ """Parses 'a+be' string into a tuple (a, b)."""
550
390
  s = s.strip().replace(" ", "").lower()
551
391
  if not s:
552
392
  return 0.0, 0.0
553
-
554
- # Eğer 'e' yoksa, bu standart bir sayıdır (b=0)
555
393
  if 'e' not in s:
556
394
  return float(s), 0.0
557
395
 
558
- # 'a+be' formatını regex ile ayrıştır
559
- # Örnekler: 5+3e, -3.1-4.5e, +2e, e, -e
560
- match = re.match(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)e$", s)
396
+ pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)e$")
397
+ match = pattern.match(s)
561
398
  if not match:
562
- # Sadece +e veya -e durumları için
563
- match = re.match(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-])e$", s)
564
-
565
- if not match:
566
- raise ValueError(f"Geçersiz hiperreel format: {s}")
399
+ raise ValueError(f"Invalid hyperreal format: {s}")
567
400
 
568
401
  parts = match.groupdict()
569
- a_part = parts.get('a')
402
+ a_part = parts.get('a') or "0"
570
403
  b_part = parts.get('b')
571
-
572
- a = float(a_part) if a_part else 0.0
573
404
 
574
- if b_part is None or b_part == '' or b_part == '+':
575
- b = 1.0
576
- elif b_part == '-':
577
- b = -1.0
405
+ if b_part in (None, "", "+"):
406
+ b_val = 1.0
407
+ elif b_part == "-":
408
+ b_val = -1.0
578
409
  else:
579
- b = float(b_part)
410
+ b_val = float(b_part)
580
411
 
581
- return a, b
412
+ return float(a_part), b_val
582
413
 
583
414
  def _parse_quaternion(s: str) -> np.quaternion:
584
- """
585
- Kullanıcıdan gelen metin girdisini ('a+bi+cj+dk' veya sadece skaler)
586
- bir kuaterniyon nesnesine çevirir.
587
-
588
- Örnekler:
589
- - '2.5' -> quaternion(2.5, 2.5, 2.5, 2.5)
590
- - '2.5+2.5i+2.5j+2.5k' -> quaternion(2.5, 2.5, 2.5, 2.5)
591
- - '1-2i+3.5j-k' -> quaternion(1, -2, 3.5, -1)
592
- """
415
+ """Parses user string ('a+bi+cj+dk' or scalar) into a quaternion."""
593
416
  s_clean = s.replace(" ", "").lower()
594
417
  if not s_clean:
595
- raise ValueError("Girdi boş olamaz.")
418
+ raise ValueError("Input cannot be empty.")
596
419
 
597
- # Girdinin sadece bir sayı olup olmadığını kontrol et
598
420
  try:
599
421
  val = float(s_clean)
600
- # Programın orijinal mantığına göre skalerden kuaterniyon oluştur
601
422
  return np.quaternion(val, val, val, val)
602
423
  except ValueError:
603
- # Girdi tam bir kuaterniyon ifadesi, ayrıştırmaya devam et
604
424
  pass
605
425
 
606
- # Tüm kuaterniyon bileşenlerini bulmak için daha esnek bir regex
607
- # Örnek: '-10.5j', '+2i', '5', '-k' gibi parçaları yakalar
608
- pattern = re.compile(r'([+-]?\d*\.?\d+)([ijk])?')
609
- matches = pattern.findall(s_clean.replace('i', 'i ').replace('j', 'j ').replace('k', 'k ')) # Ayrıştırmayı kolaylaştır
610
-
611
- parts = {'w': 0.0, 'x': 0.0, 'y': 0.0, 'z': 0.0}
612
-
613
- # 'i', 'j', 'k' olmayan katsayıları ('-1k' gibi) düzeltmek için
614
- s_temp = s_clean
615
- for val_str, comp in re.findall(r'([+-])([ijk])', s_clean):
616
- s_temp = s_temp.replace(val_str+comp, f'{val_str}1{comp}')
426
+ s_temp = re.sub(r'([+-])([ijk])', r'\g<1>1\g<2>', s_clean)
427
+ if s_temp.startswith(('i', 'j', 'k')):
428
+ s_temp = '1' + s_temp
617
429
 
430
+ pattern = re.compile(r'([+-]?\d*\.?\d*)([ijk])?')
618
431
  matches = pattern.findall(s_temp)
619
-
620
- if not matches:
621
- raise ValueError(f"Geçersiz kuaterniyon formatı: '{s}'")
622
-
432
+
433
+ parts = {'w': 0.0, 'x': 0.0, 'y': 0.0, 'z': 0.0}
623
434
  for value_str, component in matches:
435
+ if not value_str:
436
+ continue
624
437
  value = float(value_str)
625
438
  if component == 'i':
626
439
  parts['x'] += value
@@ -628,141 +441,98 @@ def _parse_quaternion(s: str) -> np.quaternion:
628
441
  parts['y'] += value
629
442
  elif component == 'k':
630
443
  parts['z'] += value
631
- else: # Reel kısım
444
+ else:
632
445
  parts['w'] += value
633
446
 
634
447
  return np.quaternion(parts['w'], parts['x'], parts['y'], parts['z'])
635
448
 
636
- def get_random_type(num_iterations, fixed_start_raw="0", fixed_add_base_scalar=9.0):
637
- """
638
- Generates Keçeci Numbers for a randomly selected type using fixed parameters.
639
- (Updated with the full list of 11 types and compatible with the new get_with_params signature)
640
- """
641
- # Rastgele sayı üretme aralığı 11 tipe göre güncellendi.
449
+ def get_random_type(num_iterations: int, fixed_start_raw: str = "0", fixed_add_base_scalar: float = 9.0) -> List[Any]:
450
+ """Generates Keçeci Numbers for a randomly selected type."""
642
451
  random_type_choice = random.randint(1, 11)
643
-
644
- # Kullanıcının sağladığı tam liste eklendi.
645
452
  type_names_list = [
646
453
  "Positive Real", "Negative Real", "Complex", "Float", "Rational",
647
454
  "Quaternion", "Neutrosophic", "Neutro-Complex", "Hyperreal",
648
455
  "Bicomplex", "Neutro-Bicomplex"
649
456
  ]
650
-
651
- # Listenin indeksi 0'dan başladığı için random_type_choice-1 kullanılır.
652
457
  print(f"\nRandomly selected Keçeci Number Type: {random_type_choice} ({type_names_list[random_type_choice-1]})")
653
458
 
654
- # get_with_params fonksiyonu sadeleştirilmiş haliyle çağrılıyor.
655
- # Beklenmeyen 'random_range_factor' veya 'fixed_params' argümanları yok.
656
- generated_sequence = get_with_params(
459
+ return get_with_params(
657
460
  kececi_type_choice=random_type_choice,
658
461
  iterations=num_iterations,
659
462
  start_value_raw=fixed_start_raw,
660
463
  add_value_base_scalar=fixed_add_base_scalar
661
464
  )
662
-
663
- return generated_sequence
664
465
 
665
466
  # ==============================================================================
666
467
  # --- CORE GENERATOR ---
667
468
  # ==============================================================================
668
469
 
669
- def unified_generator(kececi_type, start_input_raw, add_input_base_scalar, iterations):
670
- """
671
- Herhangi bir desteklenen türde Keçeci Sayı dizileri üreten çekirdek motor.
672
- Bu sürüm, tüm tipler için sağlam tür dönüştürme ve özel format ayrıştırma içerir.
673
- """
470
+ def unified_generator(kececi_type: int, start_input_raw: str, add_input_base_scalar: float, iterations: int) -> List[Any]:
471
+ """Core engine to generate Keçeci Number sequences."""
674
472
  current_value = None
675
473
  add_value_typed = None
676
474
  ask_unit = None
677
475
  use_integer_division = False
678
476
 
679
477
  try:
680
- # --- Adım 1: Keçeci Türüne Göre Başlatma ---
681
478
  a_float = float(add_input_base_scalar)
682
479
 
683
480
  if kececi_type in [TYPE_POSITIVE_REAL, TYPE_NEGATIVE_REAL]:
684
- s_int = int(float(start_input_raw))
685
- current_value = s_int
481
+ current_value = int(float(start_input_raw))
686
482
  add_value_typed = int(a_float)
687
483
  ask_unit = 1
688
484
  use_integer_division = True
689
-
690
485
  elif kececi_type == TYPE_FLOAT:
691
486
  current_value = float(start_input_raw)
692
487
  add_value_typed = a_float
693
488
  ask_unit = 1.0
694
-
695
489
  elif kececi_type == TYPE_RATIONAL:
696
490
  current_value = Fraction(start_input_raw)
697
491
  add_value_typed = Fraction(add_input_base_scalar)
698
492
  ask_unit = Fraction(1)
699
-
700
493
  elif kececi_type == TYPE_COMPLEX:
701
494
  current_value = _parse_complex(start_input_raw)
702
495
  add_value_typed = complex(a_float, a_float)
703
496
  ask_unit = 1 + 1j
704
-
705
497
  elif kececi_type == TYPE_NEUTROSOPHIC:
706
498
  a, b = _parse_neutrosophic(start_input_raw)
707
499
  current_value = NeutrosophicNumber(a, b)
708
500
  add_value_typed = NeutrosophicNumber(a_float, 0)
709
501
  ask_unit = NeutrosophicNumber(1, 1)
710
-
711
- # --- YENİ EKLENEN/DÜZELTİLEN BLOKLAR ---
712
-
713
- elif kececi_type == TYPE_NEUTROSOPHIC_COMPLEX: # HATA DÜZELTİLDİ
502
+ elif kececi_type == TYPE_NEUTROSOPHIC_COMPLEX:
714
503
  s_complex = _parse_complex(start_input_raw)
715
- # Başlangıç indeterminacy değerini 0 olarak varsayalım
716
504
  current_value = NeutrosophicComplexNumber(s_complex.real, s_complex.imag, 0.0)
717
- # Artış, deterministik reel kısma etki eder
718
505
  add_value_typed = NeutrosophicComplexNumber(a_float, 0.0, 0.0)
719
506
  ask_unit = NeutrosophicComplexNumber(1, 1, 1)
720
-
721
- elif kececi_type == TYPE_HYPERREAL: # HATA DÜZELTİLDİ
507
+ elif kececi_type == TYPE_HYPERREAL:
722
508
  a, b = _parse_hyperreal(start_input_raw)
723
- # 'a' reel kısmı, 'b' ise sonsuz küçükleri ölçekler
724
509
  sequence_list = [a + b / n for n in range(1, 11)]
725
510
  current_value = HyperrealNumber(sequence_list)
726
- # Artış, sadece standart (ilk) reel kısma etki eder
727
511
  add_sequence = [a_float] + [0.0] * 9
728
512
  add_value_typed = HyperrealNumber(add_sequence)
729
513
  ask_unit = HyperrealNumber([1.0] * 10)
730
-
731
- elif kececi_type == TYPE_BICOMPLEX: # Mantık aynı, sadece ayrıştırıcıyı kullanıyor
514
+ elif kececi_type == TYPE_BICOMPLEX:
732
515
  s_complex = _parse_complex(start_input_raw)
733
516
  a_complex = complex(a_float)
734
517
  current_value = BicomplexNumber(s_complex, s_complex / 2)
735
518
  add_value_typed = BicomplexNumber(a_complex, a_complex / 2)
736
519
  ask_unit = BicomplexNumber(complex(1, 1), complex(0.5, 0.5))
737
-
738
- elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX: # HATA DÜZELTİLDİ
520
+ elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
739
521
  s_complex = _parse_complex(start_input_raw)
740
- # Başlangıç değeri olarak kompleks sayıyı kullanıp diğer 6 bileşeni 0 yapalım
741
522
  current_value = NeutrosophicBicomplexNumber(s_complex.real, s_complex.imag, 0, 0, 0, 0, 0, 0)
742
- # Artış, sadece ana reel kısma etki eder
743
523
  add_value_typed = NeutrosophicBicomplexNumber(a_float, 0, 0, 0, 0, 0, 0, 0)
744
524
  ask_unit = NeutrosophicBicomplexNumber(*([1.0] * 8))
745
-
746
- # --- DİĞER TİPLER ---
747
-
748
525
  elif kececi_type == TYPE_QUATERNION:
749
- # Artık girdiyi doğrudan float'a çevirmek yerine,
750
- # hem skaler hem de tam ifadeyi ayrıştırabilen fonksiyonu kullanıyoruz.
751
526
  current_value = _parse_quaternion(start_input_raw)
752
-
753
- # Artırım değeri (add_value) genellikle basit bir skalerdir,
754
- # bu yüzden bu kısım aynı kalabilir.
755
527
  add_value_typed = np.quaternion(a_float, a_float, a_float, a_float)
756
528
  ask_unit = np.quaternion(1, 1, 1, 1)
757
-
758
529
  else:
759
- raise ValueError(f"Geçersiz veya desteklenmeyen Keçeci Sayı Tipi: {kececi_type}")
530
+ raise ValueError(f"Invalid Keçeci Number Type: {kececi_type}")
760
531
 
761
532
  except (ValueError, TypeError) as e:
762
- print(f"HATA: Tip {kececi_type} için '{start_input_raw}' girdisiyle başlatma başarısız: {e}")
533
+ print(f"ERROR: Failed to initialize type {kececi_type} with input '{start_input_raw}': {e}")
763
534
  return []
764
535
 
765
- # --- Adım 2: İterasyon Döngüsü ---
766
536
  sequence = [current_value]
767
537
  last_divisor_used = None
768
538
  ask_counter = 0
@@ -802,44 +572,29 @@ def unified_generator(kececi_type, start_input_raw, add_input_base_scalar, itera
802
572
 
803
573
  return sequence
804
574
 
805
- def print_detailed_report(sequence, params):
806
- """
807
- Generates and prints a detailed report of the Keçeci sequence results.
808
-
809
- Args:
810
- sequence (list): The generated Keçeci sequence.
811
- params (dict): A dictionary containing the generation parameters.
812
- """
575
+ def print_detailed_report(sequence: List[Any], params: Dict[str, Any]):
576
+ """Generates and prints a detailed report of the sequence results."""
813
577
  if not sequence:
814
- print("\n--- REPORT ---")
815
- print("Sequence could not be generated. No report to show.")
578
+ print("\n--- REPORT ---\nSequence could not be generated.")
816
579
  return
817
580
 
818
581
  print("\n\n" + "="*50)
819
582
  print("--- DETAILED SEQUENCE REPORT ---")
820
583
  print("="*50)
821
584
 
822
- # Parametreleri yazdır
823
585
  print("\n[Parameters Used]")
824
- print(f" - Keçeci Type: {params['type_name']} ({params['type_choice']})")
586
+ print(f" - Keçeci Type: {params.get('type_name', 'N/A')} ({params['type_choice']})")
825
587
  print(f" - Start Value: '{params['start_val']}'")
826
588
  print(f" - Increment: {params['add_val']}")
827
589
  print(f" - Keçeci Steps: {params['steps']}")
828
590
 
829
- # Dizi Özeti
830
591
  print("\n[Sequence Summary]")
831
592
  print(f" - Total Numbers Generated: {len(sequence)}")
832
593
 
833
- # Keçeci Asal Sayısı (KPN) sonucunu bul ve yazdır
834
594
  kpn = find_kececi_prime_number(sequence)
835
- if kpn is not None:
836
- print(f" - Keçeci Prime Number (KPN): {kpn}")
837
- else:
838
- print(" - Keçeci Prime Number (KPN): Not found in this sequence.")
595
+ print(f" - Keçeci Prime Number (KPN): {kpn if kpn is not None else 'Not found'}")
839
596
 
840
- # Dizi Önizlemesi
841
597
  print("\n[Sequence Preview]")
842
- # Dizinin tamamını yazdırmadan önce bir önizleme sunalım
843
598
  preview_count = min(len(sequence), 5)
844
599
  print(f" --- First {preview_count} Numbers ---")
845
600
  for i in range(preview_count):
@@ -852,7 +607,6 @@ def print_detailed_report(sequence, params):
852
607
 
853
608
  print("\n" + "="*50)
854
609
 
855
- # Kullanıcıya tüm diziyi görmek isteyip istemediğini sor
856
610
  while True:
857
611
  show_all = input("Do you want to print the full sequence? (y/n): ").lower().strip()
858
612
  if show_all in ['y', 'n']:
@@ -868,18 +622,13 @@ def print_detailed_report(sequence, params):
868
622
  # --- HIGH-LEVEL CONTROL FUNCTIONS ---
869
623
  # ==============================================================================
870
624
 
871
- def get_with_params(kececi_type_choice, iterations, start_value_raw="0", add_value_base_scalar=9.0):
872
- """
873
- Generates Keçeci Numbers with specified parameters.
874
- """
625
+ def get_with_params(kececi_type_choice: int, iterations: int, start_value_raw: str = "0", add_value_base_scalar: float = 9.0) -> List[Any]:
626
+ """Generates Keçeci Numbers with specified parameters."""
875
627
  print(f"\n--- Generating Sequence: Type {kececi_type_choice}, Steps {iterations} ---")
876
628
  print(f"Start: '{start_value_raw}', Increment: {add_value_base_scalar}")
877
629
 
878
630
  generated_sequence = unified_generator(
879
- kececi_type_choice,
880
- start_value_raw,
881
- add_value_base_scalar,
882
- iterations
631
+ kececi_type_choice, start_value_raw, add_value_base_scalar, iterations
883
632
  )
884
633
 
885
634
  if generated_sequence:
@@ -894,11 +643,8 @@ def get_with_params(kececi_type_choice, iterations, start_value_raw="0", add_val
894
643
 
895
644
  return generated_sequence
896
645
 
897
- def get_interactive():
898
- """
899
- Interactively gets parameters from the user and generates Keçeci Numbers.
900
- This version only gets data and returns the sequence without plotting.
901
- """
646
+ def get_interactive() -> Tuple[List[Any], Dict[str, Any]]:
647
+ """Interactively gets parameters from the user to generate a sequence."""
902
648
  print("\n--- Keçeci Number Interactive Generator ---")
903
649
  print(" 1: Positive Real 2: Negative Real 3: Complex")
904
650
  print(" 4: Float 5: Rational 6: Quaternion")
@@ -907,242 +653,156 @@ def get_interactive():
907
653
 
908
654
  while True:
909
655
  try:
910
- type_choice = int(input(f"Select Keçeci Number Type (1-11): "))
911
- if 1 <= type_choice <= 11: break
912
- else: print("Invalid type. Please enter a number between 1 and 11.")
913
- except ValueError: print("Invalid input. Please enter a number.")
656
+ type_choice = int(input("Select Keçeci Number Type (1-11): "))
657
+ if 1 <= type_choice <= 11:
658
+ break
659
+ print("Invalid type. Please enter a number between 1 and 11.")
660
+ except ValueError:
661
+ print("Invalid input. Please enter a number.")
914
662
 
915
- # Her tip için özel başlangıç değeri istemleri (prompts)
916
663
  prompts = {
917
- 1: "Enter positive integer start (e.g., '10'): ",
918
- 2: "Enter negative integer start (e.g., '-5'): ",
919
- 3: "Enter complex start (e.g., '3+4j' or '3' for 3+3j): ",
920
- 4: "Enter float start (e.g., '3.14' or '-0.5'): ",
921
- 5: "Enter rational start (e.g., '7/2' or '5' for 5/1): ",
922
- 6: "Enter scalar for quaternion base (e.g., '2.5' for 2.5+2.5i+2.5j+2.5k): ",
923
- 7: "Enter neutrosophic start (e.g., '5+2I' or '7'): ",
924
- 8: "Enter complex base for neutro-complex (e.g., '1-2j'): ",
925
- 9: "Enter hyperreal start (e.g., '5+3e' or '10'): ",
664
+ 1: "Enter positive integer start (e.g., '10'): ",
665
+ 2: "Enter negative integer start (e.g., '-5'): ",
666
+ 3: "Enter complex start (e.g., '3+4j' or '3' for 3+3j): ",
667
+ 4: "Enter float start (e.g., '3.14'): ",
668
+ 5: "Enter rational start (e.g., '7/2' or '5'): ",
669
+ 6: "Enter quaternion (e.g., '1+2i-3j+k' or '2.5'): ",
670
+ 7: "Enter neutrosophic start (e.g., '5+2I' or '7'): ",
671
+ 8: "Enter complex base for neutro-complex (e.g., '1-2j'): ",
672
+ 9: "Enter hyperreal start (e.g., '5+3e' or '10'): ",
926
673
  10: "Enter complex base for bicomplex (e.g., '2+1j'): ",
927
674
  11: "Enter complex base for neutro-bicomplex (e.g., '1+2j'): "
928
675
  }
929
676
 
930
- # Seçilen tipe göre doğru istemi al, yoksa genel bir istem kullan
931
677
  start_prompt = prompts.get(type_choice, "Enter starting value: ")
932
-
933
678
  start_input_val_raw = input(start_prompt)
934
- add_base_scalar_val = float(input("Enter base scalar increment (e.g., 9.0 for positive, -3.0 for negative): "))
679
+ add_base_scalar_val = float(input("Enter base scalar increment (e.g., 9.0): "))
935
680
  num_kececi_steps = int(input("Enter number of Keçeci steps (e.g., 15): "))
936
681
 
937
- # Diziyi oluştur ve çizdir
938
682
  sequence = get_with_params(type_choice, num_kececi_steps, start_input_val_raw, add_base_scalar_val)
939
- if sequence:
940
- # sequence adı altında bir isim çakışması olmaması için başlığı değiştiriyoruz.
941
- plot_title = f"Keçeci Type {type_choice} Sequence"
942
- #plot_numbers(sequence, plot_title)
943
- #plt.show() # Grafiği göstermek için
944
-
945
- # Fonksiyonun, ana kodun kullanabilmesi için tüm önemli bilgileri döndürmesini sağlıyoruz.
946
- return sequence, type_choice, start_input_val_raw, add_base_scalar_val, num_kececi_steps
683
+
684
+ params = {
685
+ "type_choice": type_choice,
686
+ "start_val": start_input_val_raw,
687
+ "add_val": add_base_scalar_val,
688
+ "steps": num_kececi_steps
689
+ }
690
+ return sequence, params
947
691
 
948
692
  # ==============================================================================
949
693
  # --- ANALYSIS AND PLOTTING ---
950
694
  # ==============================================================================
951
695
 
952
- def find_kececi_prime_number(kececi_numbers_list):
953
- """
954
- Finds the Keçeci Prime Number from a generated sequence.
955
-
956
- The Keçeci Prime is the integer representation of the most frequent number
957
- in the sequence whose principal component is itself prime. Ties in frequency
958
- are broken by choosing the larger prime number.
959
- """
696
+ def find_kececi_prime_number(kececi_numbers_list: List[Any]) -> Optional[int]:
697
+ """Finds the Keçeci Prime Number from a generated sequence."""
960
698
  if not kececi_numbers_list:
961
699
  return None
962
700
 
963
- # Extract integer representations of numbers that are prime
964
- integer_prime_reps = []
965
- for num in kececi_numbers_list:
966
- if is_prime(num):
967
- # This logic is duplicated from is_prime to get the value itself
968
- value = 0
969
- if isinstance(num, (int, float, Fraction)): value = abs(int(num))
970
- elif isinstance(num, complex): value = abs(int(num.real))
971
- elif isinstance(num, np.quaternion): value = abs(int(num.w))
972
- elif isinstance(num, NeutrosophicNumber): value = abs(int(num.a))
973
- elif isinstance(num, NeutrosophicComplexNumber): value = abs(int(num.real))
974
- elif isinstance(num, HyperrealNumber): value = abs(int(num.sequence[0])) if num.sequence else 0
975
- elif isinstance(num, BicomplexNumber): value = abs(int(num.z1.real))
976
- elif isinstance(num, NeutrosophicBicomplexNumber): value = abs(int(num.real))
977
- integer_prime_reps.append(value)
701
+ integer_prime_reps = [
702
+ rep for num in kececi_numbers_list
703
+ if is_prime(num) and (rep := _get_integer_representation(num)) is not None
704
+ ]
978
705
 
979
706
  if not integer_prime_reps:
980
707
  return None
981
708
 
982
- # Count frequencies of these prime integers
983
709
  counts = collections.Counter(integer_prime_reps)
984
-
985
- # Find primes that repeat
986
710
  repeating_primes = [(freq, prime) for prime, freq in counts.items() if freq > 1]
987
-
988
711
  if not repeating_primes:
989
712
  return None
990
713
 
991
- # Find the one with the highest frequency, using the prime value as a tie-breaker
992
714
  _, best_prime = max(repeating_primes)
993
715
  return best_prime
994
716
 
995
- def plot_numbers(sequence, title="Keçeci Number Sequence Analysis"):
996
- """
997
- Plots the generated Keçeci Number sequence with appropriate, detailed
998
- visualizations for each number type.
999
- """
717
+ def plot_numbers(sequence: List[Any], title: str = "Keçeci Number Sequence Analysis"):
718
+ """Plots the generated sequence with detailed visualizations for each type."""
1000
719
  plt.style.use('seaborn-v0_8-whitegrid')
1001
720
 
1002
721
  if not sequence:
1003
722
  print("Sequence is empty, nothing to plot.")
1004
723
  return
1005
724
 
1006
- fig = plt.figure(figsize=(16, 9)) # Daha geniş bir görünüm için boyut ayarlandı
725
+ fig = plt.figure(figsize=(16, 9))
1007
726
  plt.suptitle(title, fontsize=16, y=0.98)
1008
727
  first_elem = sequence[0]
1009
728
 
1010
- # --- Her Türe Özel Çizim Mantığı ---
1011
-
1012
729
  if isinstance(first_elem, (int, float, Fraction)):
1013
730
  ax = fig.add_subplot(1, 1, 1)
1014
731
  ax.plot([float(x) for x in sequence], 'o-', label="Value")
1015
732
  ax.set_title("Value over Iterations")
1016
- ax.set_xlabel("Index")
1017
- ax.set_ylabel("Value")
1018
- ax.legend()
733
+ ax.set_xlabel("Index"), ax.set_ylabel("Value"), ax.legend()
1019
734
 
1020
735
  elif isinstance(first_elem, complex):
1021
736
  gs = GridSpec(2, 2, figure=fig)
1022
- ax1 = fig.add_subplot(gs[0, 0])
1023
- ax2 = fig.add_subplot(gs[0, 1])
1024
- ax3 = fig.add_subplot(gs[1, :])
1025
-
1026
- real_parts = [c.real for c in sequence]
1027
- imag_parts = [c.imag for c in sequence]
1028
-
1029
- ax1.plot(real_parts, 'o-', label='Real Part')
1030
- ax1.set_title("Real Part"); ax1.legend()
1031
-
1032
- ax2.plot(imag_parts, 'o-', color='red', label='Imaginary Part')
1033
- ax2.set_title("Imaginary Part"); ax2.legend()
1034
-
737
+ ax1, ax2, ax3 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[1, :])
738
+ real_parts, imag_parts = [c.real for c in sequence], [c.imag for c in sequence]
739
+ ax1.plot(real_parts, 'o-', label='Real Part'), ax1.set_title("Real Part"), ax1.legend()
740
+ ax2.plot(imag_parts, 'o-', color='red', label='Imaginary Part'), ax2.set_title("Imaginary Part"), ax2.legend()
1035
741
  ax3.plot(real_parts, imag_parts, '.-', label='Trajectory')
1036
742
  ax3.scatter(real_parts[0], imag_parts[0], c='g', s=100, label='Start', zorder=5)
1037
743
  ax3.scatter(real_parts[-1], imag_parts[-1], c='r', s=100, label='End', zorder=5)
1038
- ax3.set_title("Trajectory in Complex Plane"); ax3.set_xlabel("Real"); ax3.set_ylabel("Imaginary"); ax3.legend(); ax3.axis('equal')
744
+ ax3.set_title("Trajectory in Complex Plane"), ax3.set_xlabel("Real"), ax3.set_ylabel("Imaginary"), ax3.legend(), ax3.axis('equal')
1039
745
 
1040
746
  elif isinstance(first_elem, np.quaternion):
1041
747
  gs = GridSpec(2, 1, figure=fig)
1042
- ax1 = fig.add_subplot(gs[0, 0])
1043
- ax2 = fig.add_subplot(gs[1, 0], sharex=ax1) # X eksenini paylaş
1044
-
1045
- ax1.plot([q.w for q in sequence], 'o-', label='w (scalar)')
1046
- ax1.plot([q.x for q in sequence], 's--', label='x')
1047
- ax1.plot([q.y for q in sequence], '^--', label='y')
1048
- ax1.plot([q.z for q in sequence], 'd--', label='z')
1049
- ax1.set_title("Quaternion Components over Iterations"); ax1.legend()
1050
-
1051
- magnitudes = [np.sqrt(q.w**2 + q.x**2 + q.y**2 + q.z**2) for q in sequence]
1052
- ax2.plot(magnitudes, 'o-', color='purple', label='Magnitude')
1053
- ax2.set_title("Quaternion Magnitude over Iterations"); ax2.legend()
1054
- ax2.set_xlabel("Index")
748
+ ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0], sharex=ax1)
749
+ ax1.plot([q.w for q in sequence], 'o-', label='w (scalar)'), ax1.plot([q.x for q in sequence], 's--', label='x')
750
+ ax1.plot([q.y for q in sequence], '^--', label='y'), ax1.plot([q.z for q in sequence], 'd--', label='z')
751
+ ax1.set_title("Quaternion Components"), ax1.legend()
752
+ magnitudes = [abs(q) for q in sequence]
753
+ ax2.plot(magnitudes, 'o-', color='purple', label='Magnitude'), ax2.set_title("Magnitude"), ax2.legend(), ax2.set_xlabel("Index")
1055
754
 
1056
755
  elif isinstance(first_elem, BicomplexNumber):
1057
756
  gs = GridSpec(2, 2, figure=fig)
1058
- ax1 = fig.add_subplot(gs[0, 0]); ax2 = fig.add_subplot(gs[0, 1])
1059
- ax3 = fig.add_subplot(gs[1, 0]); ax4 = fig.add_subplot(gs[1, 1])
1060
-
1061
- z1r = [x.z1.real for x in sequence]; z1i = [x.z1.imag for x in sequence]
1062
- z2r = [x.z2.real for x in sequence]; z2i = [x.z2.imag for x in sequence]
1063
-
1064
- ax1.plot(z1r, label='z1.real'); ax1.plot(z1i, label='z1.imag')
1065
- ax1.set_title("Component z1"); ax1.legend()
1066
-
1067
- ax2.plot(z2r, label='z2.real'); ax2.plot(z2i, label='z2.imag')
1068
- ax2.set_title("Component z2"); ax2.legend()
1069
-
1070
- ax3.plot(z1r, z1i, '.-'); ax3.set_title("z1 Trajectory"); ax3.set_xlabel("Real"); ax3.set_ylabel("Imaginary")
1071
- ax4.plot(z2r, z2i, '.-'); ax4.set_title("z2 Trajectory"); ax4.set_xlabel("Real"); ax4.set_ylabel("Imaginary")
757
+ ax1, ax2, ax3, ax4 = fig.add_subplot(gs[0,0]), fig.add_subplot(gs[0,1]), fig.add_subplot(gs[1,0]), fig.add_subplot(gs[1,1])
758
+ z1r, z1i = [x.z1.real for x in sequence], [x.z1.imag for x in sequence]
759
+ z2r, z2i = [x.z2.real for x in sequence], [x.z2.imag for x in sequence]
760
+ ax1.plot(z1r, label='z1.real'), ax1.plot(z1i, label='z1.imag'), ax1.set_title("Component z1"), ax1.legend()
761
+ ax2.plot(z2r, label='z2.real'), ax2.plot(z2i, label='z2.imag'), ax2.set_title("Component z2"), ax2.legend()
762
+ ax3.plot(z1r, z1i, '.-'), ax3.set_title("z1 Trajectory"), ax3.set_xlabel("Real"), ax3.set_ylabel("Imaginary")
763
+ ax4.plot(z2r, z2i, '.-'), ax4.set_title("z2 Trajectory"), ax4.set_xlabel("Real"), ax4.set_ylabel("Imaginary")
1072
764
 
1073
765
  elif isinstance(first_elem, NeutrosophicNumber):
1074
766
  gs = GridSpec(1, 2, figure=fig)
1075
- ax1 = fig.add_subplot(gs[0, 0]); ax2 = fig.add_subplot(gs[0, 1])
1076
-
1077
- a = [x.a for x in sequence]; b = [x.b for x in sequence]
1078
- ax1.plot(a, label='Determinate (a)'); ax1.plot(b, label='Indeterminate (b)')
1079
- ax1.set_title("Components over Iterations"); ax1.legend()
1080
-
767
+ ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1])
768
+ a, b = [x.a for x in sequence], [x.b for x in sequence]
769
+ ax1.plot(a, label='Determinate (a)'), ax1.plot(b, label='Indeterminate (b)'), ax1.set_title("Components"), ax1.legend()
1081
770
  sc = ax2.scatter(a, b, c=range(len(a)), cmap='viridis')
1082
- ax2.set_title("Trajectory (colored by time)"); ax2.set_xlabel("Determinate Part"); ax2.set_ylabel("Indeterminate Part"); fig.colorbar(sc, ax=ax2, label="Iteration")
771
+ ax2.set_title("Trajectory"), ax2.set_xlabel("Determinate"), ax2.set_ylabel("Indeterminate"), fig.colorbar(sc, ax=ax2, label="Iteration")
1083
772
 
1084
773
  elif isinstance(first_elem, NeutrosophicComplexNumber):
1085
774
  gs = GridSpec(2, 1, figure=fig)
1086
- ax1 = fig.add_subplot(gs[0, 0]); ax2 = fig.add_subplot(gs[1, 0])
1087
-
1088
- r = [x.real for x in sequence]; i = [x.imag for x in sequence]; ind = [x.indeterminacy for x in sequence]
1089
- ax1.plot(r, label='Real'); ax1.plot(i, label='Imag'); ax1.plot(ind, label='Indeterminacy', linestyle=':')
1090
- ax1.set_title("Components over Iterations"); ax1.legend()
1091
-
775
+ ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0])
776
+ r, i, ind = [x.real for x in sequence], [x.imag for x in sequence], [x.indeterminacy for x in sequence]
777
+ ax1.plot(r, label='Real'), ax1.plot(i, label='Imag'), ax1.plot(ind, label='Indeterminacy', linestyle=':')
778
+ ax1.set_title("Components"), ax1.legend()
1092
779
  sc = ax2.scatter(r, i, c=ind, cmap='magma', s=20)
1093
- ax2.set_title("Trajectory in Complex Plane (colored by Indeterminacy)");
1094
- ax2.set_xlabel("Real Part"); ax2.set_ylabel("Imaginary Part");
1095
- fig.colorbar(sc, ax=ax2, label='Indeterminacy')
1096
- ax2.axis('equal')
780
+ ax2.set_title("Trajectory (colored by Indeterminacy)"), ax2.set_xlabel("Real"), ax2.set_ylabel("Imaginary")
781
+ fig.colorbar(sc, ax=ax2, label='Indeterminacy'), ax2.axis('equal')
1097
782
 
1098
- # --- YENİ EKLENEN BLOKLAR ---
1099
-
1100
783
  elif isinstance(first_elem, HyperrealNumber):
1101
784
  gs = GridSpec(2, 1, figure=fig)
1102
- ax1 = fig.add_subplot(gs[0, 0])
1103
- ax2 = fig.add_subplot(gs[1, 0])
1104
-
1105
- # İlk birkaç bileşeni çiz
1106
- num_components_to_plot = min(len(first_elem.sequence), 4)
1107
- for i in range(num_components_to_plot):
1108
- comp_data = [h.sequence[i] for h in sequence]
1109
- ax1.plot(comp_data, label=f'Component {i}')
1110
- ax1.set_title("Hyperreal Components over Iterations"); ax1.legend()
1111
-
1112
- # En önemli iki bileşenin yörüngesini çiz
1113
- comp0 = [h.sequence[0] for h in sequence]
1114
- comp1 = [h.sequence[1] for h in sequence]
785
+ ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0])
786
+ num_components = min(len(first_elem.sequence), 4)
787
+ for i in range(num_components):
788
+ ax1.plot([h.sequence[i] for h in sequence], label=f'Comp {i}')
789
+ ax1.set_title("Hyperreal Components"), ax1.legend()
790
+ comp0, comp1 = [h.sequence[0] for h in sequence], [h.sequence[1] for h in sequence]
1115
791
  sc = ax2.scatter(comp0, comp1, c=range(len(comp0)), cmap='plasma')
1116
- ax2.set_title("Trajectory in Standard-Infinitesimal Plane (C0 vs C1)")
1117
- ax2.set_xlabel("Standard Part (C0)"); ax2.set_ylabel("Primary Infinitesimal (C1)")
1118
- fig.colorbar(sc, ax=ax2, label="Iteration")
792
+ ax2.set_title("Trajectory (C0 vs C1)"), ax2.set_xlabel("C0"), ax2.set_ylabel("C1"), fig.colorbar(sc, ax=ax2, label="Iteration")
1119
793
 
1120
794
  elif isinstance(first_elem, NeutrosophicBicomplexNumber):
1121
795
  gs = GridSpec(2, 2, figure=fig)
1122
- ax1 = fig.add_subplot(gs[0, 0]); ax2 = fig.add_subplot(gs[0, 1])
1123
- ax3 = fig.add_subplot(gs[1, 0]); ax4 = fig.add_subplot(gs[1, 1])
1124
-
1125
- # Ana 4 yörüngeyi çizelim
1126
- r = [n.real for n in sequence]; i = [n.imag for n in sequence]
1127
- ax1.plot(r, i, '.-', label='(1, i1)')
1128
- ax1.set_title("Primary Deterministic Plane"); ax1.legend()
1129
-
1130
- nr = [n.neut_real for n in sequence]; ni = [n.neut_imag for n in sequence]
1131
- ax2.plot(nr, ni, '.-', label='(I, I*i1)')
1132
- ax2.set_title("Primary Neutrosophic Plane"); ax2.legend()
1133
-
1134
- jr = [n.j_real for n in sequence]; ji = [n.j_imag for n in sequence]
1135
- ax3.plot(jr, ji, '.-', label='(i2, i1*i2)')
1136
- ax3.set_title("Secondary Deterministic Plane"); ax3.legend()
796
+ ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1])
797
+ ax3, ax4 = fig.add_subplot(gs[1, 0]), fig.add_subplot(gs[1, 1])
798
+ ax1.plot([n.real for n in sequence], [n.imag for n in sequence], '.-'), ax1.set_title("Primary Deterministic")
799
+ ax2.plot([n.neut_real for n in sequence], [n.neut_imag for n in sequence], '.-'), ax2.set_title("Primary Neutrosophic")
800
+ ax3.plot([n.j_real for n in sequence], [n.j_imag for n in sequence], '.-'), ax3.set_title("Secondary Deterministic")
801
+ ax4.plot([n.j_neut_real for n in sequence], [n.j_neut_imag for n in sequence], '.-'), ax4.set_title("Secondary Neutrosophic")
1137
802
 
1138
- njr = [n.j_neut_real for n in sequence]; nji = [n.j_neut_imag for n in sequence]
1139
- ax4.plot(njr, nji, '.-', label='(I*i2, I*i1*i2)')
1140
- ax4.set_title("Secondary Neutrosophic Plane"); ax4.legend()
1141
-
1142
- else: # Gelecekte eklenebilecek diğer tipler için yedek blok
803
+ else:
1143
804
  ax = fig.add_subplot(1, 1, 1)
1144
- ax.text(0.5, 0.5, f"Plotting for type '{type(first_elem).__name__}' is not specifically implemented.",
1145
- ha='center', va='center', fontsize=12, bbox=dict(facecolor='lightyellow'))
805
+ ax.text(0.5, 0.5, f"Plotting for '{type(first_elem).__name__}' not implemented.", ha='center')
1146
806
 
1147
807
  plt.tight_layout(rect=[0, 0, 1, 0.96])
1148
808
 
@@ -1153,45 +813,35 @@ if __name__ == "__main__":
1153
813
  print("="*60)
1154
814
  print(" Keçeci Numbers Module - Demonstration")
1155
815
  print("="*60)
1156
- print(f"This script demonstrates the generation of various Keçeci Number types.")
816
+ print("This script demonstrates the generation of various Keçeci Number types.")
1157
817
 
1158
818
  # --- Example 1: Interactive Mode ---
1159
- # To run interactive mode, uncomment the following line:
1160
- # get_interactive()
819
+ # Uncomment the following lines to run in interactive mode:
820
+ # seq, params = get_interactive()
821
+ # if seq:
822
+ # plot_numbers(seq, title=f"Keçeci Type {params['type_choice']} Sequence")
823
+ # plt.show()
1161
824
 
1162
825
  # --- Example 2: Programmatic Generation and Plotting ---
1163
- # We will generate a sequence for each type to test the system.
1164
826
  print("\nRunning programmatic tests for all 11 number types...")
1165
827
 
1166
- # Test parameters
1167
- STEPS = 15
828
+ STEPS = 30
1168
829
  START_VAL = "2.5"
1169
830
  ADD_VAL = 3.0
1170
831
 
1171
832
  all_types = {
1172
- "Positive Real": TYPE_POSITIVE_REAL,
1173
- "Negative Real": TYPE_NEGATIVE_REAL,
1174
- "Complex": TYPE_COMPLEX,
1175
- "Float": TYPE_FLOAT,
1176
- "Rational": TYPE_RATIONAL,
1177
- "Quaternion": TYPE_QUATERNION,
1178
- "Neutrosophic": TYPE_NEUTROSOPHIC,
1179
- "Neutrosophic Complex": TYPE_NEUTROSOPHIC_COMPLEX,
1180
- "Hyperreal": TYPE_HYPERREAL,
1181
- "Bicomplex": TYPE_BICOMPLEX,
1182
- "Neutrosophic Bicomplex": TYPE_NEUTROSOPHIC_BICOMPLEX
833
+ "Positive Real": TYPE_POSITIVE_REAL, "Negative Real": TYPE_NEGATIVE_REAL,
834
+ "Complex": TYPE_COMPLEX, "Float": TYPE_FLOAT, "Rational": TYPE_RATIONAL,
835
+ "Quaternion": TYPE_QUATERNION, "Neutrosophic": TYPE_NEUTROSOPHIC,
836
+ "Neutrosophic Complex": TYPE_NEUTROSOPHIC_COMPLEX, "Hyperreal": TYPE_HYPERREAL,
837
+ "Bicomplex": TYPE_BICOMPLEX, "Neutrosophic Bicomplex": TYPE_NEUTROSOPHIC_BICOMPLEX
1183
838
  }
1184
839
 
1185
- # Generate and plot for a few selected types
1186
840
  types_to_plot = [
1187
- "Complex",
1188
- "Quaternion",
1189
- "Bicomplex",
1190
- "Neutrosophic Complex"
841
+ "Complex", "Quaternion", "Bicomplex", "Neutrosophic Complex", "Hyperreal"
1191
842
  ]
1192
843
 
1193
844
  for name, type_id in all_types.items():
1194
- # Adjust start/add values for specific types if needed
1195
845
  start = "-5" if type_id == TYPE_NEGATIVE_REAL else "2+3j" if type_id in [TYPE_COMPLEX, TYPE_BICOMPLEX] else START_VAL
1196
846
 
1197
847
  seq = get_with_params(type_id, STEPS, start, ADD_VAL)