فهرست مقاله
اگر یک عدد وضعیت همزمان چند نشانه داشته باشد، نامگذاری مقدارها بهتنهایی مرز ورودی را روشن نمیکند. آیا بیت تازه پذیرفته میشود؟ صفر یعنی داده قابل استفاده است؟ عددی از یک شمارش دیگر چطور؟ در این درس، سه پرچم ساختگی حسگر را با IntFlag واقعی پایتون میسازیم و پذیرش نمایش را از تصمیم کاربرد جدا میکنیم. هیچ دستگاه، بستهٔ شبکه یا اندازهگیری واقعی در آزمایش وجود ندارد.
۱. سه پرچم مستقل، یک قرارداد ورودی

سه نام PRESENT، STALE و FAULT بهترتیب مقدارهای ۱، ۲ و ۴ دارند. در قرارداد تألیفی، اولی ادعای موجود بودن نمونه، دومی کهنه بودن و سومی اعلام خطاست. اینها سه جایگاه مستقلاند؛ ترکیب PRESENT و STALE قابل نمایش است، هرچند سیاست استفادهٔ ما آن را نمیپذیرد. خود کتابخانه صدق این ادعاها را دربارهٔ حسگر بررسی نمیکند و هیچ مهلت زمانی را هم اندازه نمیگیرد.
پرچمها بیواحدند. عدد ۴ در این طرح نه چهار میلیولت است و نه شدت بیشتر خطا؛ فقط جایگاهی متفاوت از ۱ و ۲ را انتخاب میکند. ولتاژ، زمان نمونهبرداری و شمارهٔ رکورد باید قراردادهای جدا داشته باشند. مقالهٔ اعتبارسنجی زمان اجرای دادهٔ حسگر با dataclass به آن فیلدها میپردازد؛ موضوع این درس، مجموعهٔ بیتهای شناختهشده و رفتار واقعی مرز پرچم است.
تابع parse_status فقط نوع دقیق int در بازهٔ بستهٔ صفر تا ۲۵۵ میگیرد. این ظرف هشتبیتی انتخاب آموزشی ماست؛ نه محدودیت عمومی IntFlag و نه تجزیهکنندهٔ بایتهای دستگاه. بولی، اعشاری، رشته، زیرکلاس int و هر عضو enum، حتی عضو کلاس خودمان، پیش از تبدیل رد میشوند. این تصمیم صریح دربارهٔ مبدأ ورودی است؛ برابری مقدار عددی، اجازهٔ عبور از این مرز نیست.
۲. بیت ناشناخته را با STRICT رد کنیم

کلاس SensorStatus با boundary=STRICT تعریف میشود. مطابق مرجع کامل FlagBoundary، مقدار خارج از پرچمهای مجاز در این حالت ValueError ایجاد میکند. در طرح ما، عدد ۸ جایگاه چهارم را روشن میکند و رد میشود؛ عدد ۹ نیز با وجود داشتن PRESENT، همان بیت ناشناخته را دارد. شناختن بخشی از وضعیت برای پذیرش تمام آن کافی نیست.
برای مقایسه، کلاس مستقلی با همان نامها و boundary=KEEP میسازیم. این انتخاب صریح، ۸ و ۹ را همراه بیت اضافی نگه میدارد. حفظ مقدار برای سازگاری یک رابط میتواند تصمیمی جدا باشد، ولی در مرز آموزشی ما تأیید شناختهشده بودن نیست. مسیر اصلی هرگز پس از خطای STRICT به KEEP برنمیگردد و مقدار خراب را هم بیصدا پاک نمیکند.
قرار داشتن در ظرف عددی کافی نیست: ۱۶ از ۲۵۵ کوچکتر است، اما در این طرح شناختهشده نیست. بررسی بازه، اندازهٔ ورودی را محدود میکند؛ بررسی پرچم، واژگان مجاز رابط را. اگر فرستنده بعداً پرچمی اضافه کند، پذیرش آن به بازبینی آگاهانهٔ طرح و قاعدهٔ کاربرد نیاز دارد.
در خروجی واقعی، مقدار عددی KeptStatus(9) همان ۹ است، اما پیمایش اعضای شناختهشده فقط PRESENT را نشان میدهد. بنابراین فهرست نامها را نباید جای اعتبارسنجی مقدار خام گذاشت؛ گزارشی ظاهراً ساده میتواند حضور بیت اضافی را پنهان کند. اگر قرار است وضعیت در رویداد ساختیافتهٔ حسگر ثبت شود، طرح گزارش باید تکلیف مقدار ناشناخته را پیش از انتخاب فیلدها مشخص کند.
۳. صفر، ترکیب و متمم در جهانِ تعریفشده

صفر با موفقیت ساخته میشود و یعنی هیچیک از سه پرچم روشن نیست. ارزیابی منطقی آن False است، اما معتبر بودن نمایش با مناسب بودن نمونه یکی نیست. قاعدهٔ کاربرد تألیفی ما PRESENT را لازم میداند و STALE و FAULT را منع میکند؛ بنابراین تنها وضعیت ۱ قابل استفاده است. وضعیت ۲ غیرصفر و از نظر نمایش معتبر است، ولی این قاعده را برآورده نمیکند.
بخش کامل IntFlag در راهنمای Enum ترکیب پرچمها با عملگرهای بیتی و از دست رفتن نوع در عملیات عددی را توضیح میدهد. شاهد مستقل ما روشن است: ترکیب PRESENT با خودش از راه OR مقدار ۱ میدهد، ولی جمع همان دو مقدار، عدد صحیح ۲ میسازد. پس جمع، عملیات مجموعهای مناسبی برای انباشتن پرچمهای تکراری نیست؛ درست بودن تصادفی بعضی جمعها این قرارداد را عوض نمیکند.
در نسخهٔ اجراشده، متمم PRESENT مقدار ۶ است؛ یعنی STALE و FAULT در همین جهان سهعضوی. متمم مجموعهٔ کامل، صفر میشود. این رفتار با متمم عدد صحیح ۱ که منفی ۲ است فرق دارد. همچنین سازندهٔ مستقیم SensorStatus(-1) در همین نسخه مقدار ۷ میدهد؛ پس شرط نامنفی بودنِ تابع ما را به STRICT نسبت نمیدهیم. مبدأ و دامنه را پیش از سازنده کنترل کردهایم.
۴. کد کامل و مرجع مستقلِ جایگاه بیتها

فایل intflag_boundary_contract.py را ذخیره و با دستور python intflag_boundary_contract.py اجرا کنید. اجرای ثبتشده CPython 3.14.5 و فقط کتابخانهٔ استاندارد دارد؛ نسخهٔ مستندات خواندهشده 3.14.8 است. هیچ بررسیکنندهٔ ایستای نوع اجرا نشده است. نتیجهٔ مرز، محصول شرطهای صریح تابع و فراخوانی واقعی IntFlag است؛ نوشتن یک نام نوع بهتنهایی چنین رفتاری را برای دادهٔ بیرونی ایجاد نمیکند.
"""Unitless synthetic status flags; explicit runtime boundary, not device validation."""
from enum import Enum, IntEnum, IntFlag, STRICT, KEEP
import json
import platform
class SensorStatus(IntFlag, boundary=STRICT):
PRESENT = 1
STALE = 2
FAULT = 4
class KeptStatus(IntFlag, boundary=KEEP):
PRESENT = 1
STALE = 2
FAULT = 4
class ForeignStatus(IntFlag, boundary=STRICT):
PRESENT = 1
class ForeignCode(IntEnum):
PRESENT = 1
class PlainCode(Enum):
PRESENT = 1
class IntChild(int):
pass
MAX_RAW = 255 # Own teaching input container, not an IntFlag API limit.
def parse_status(raw):
"""Exact int 0..255 in; actual STRICT constructor rejects unknown bits."""
if type(raw) is not int:
raise TypeError('An exact int is required; no bool, enum or coercion')
if not 0 <= raw <= MAX_RAW:
raise ValueError('Outside the authored unsigned eight-bit container')
return SensorStatus(raw)
def describe_status(raw):
flags = parse_status(raw)
# This is an authored application rule, not meaning supplied by IntFlag.
usable = bool(flags & SensorStatus.PRESENT) and not bool(
flags & (SensorStatus.STALE | SensorStatus.FAULT))
return {'raw': int(flags), 'active': [member.name for member in flags],
'usable': usable}
def position_oracle(raw):
"""Internal bounded nonnegative-int fixture oracle, not a public parser."""
# Materialized base-two digits and sets; no enum, bitwise mask or parser.
positions = frozenset(i for i, digit in enumerate(reversed(format(raw, '08b')))
if digit == '1')
known = frozenset((0, 1, 2))
if not positions <= known:
return None
labels = {0: 'PRESENT', 1: 'STALE', 2: 'FAULT'}
return {'raw': raw, 'active': [labels[i] for i in sorted(positions)],
'usable': positions == frozenset((0,))}
def positions(raw):
"""Independent digit-set fixture representation for valid small integers."""
return frozenset(i for i, digit in enumerate(reversed(format(raw, '08b')))
if digit == '1')
def value_from_positions(items):
return sum(2 ** i for i in items)
def rejects(call, exception):
try:
call()
except exception:
return True
return False
def run_example():
expected = [
{'raw': 0, 'active': [], 'usable': False},
{'raw': 1, 'active': ['PRESENT'], 'usable': True},
{'raw': 2, 'active': ['STALE'], 'usable': False},
{'raw': 3, 'active': ['PRESENT', 'STALE'], 'usable': False},
{'raw': 4, 'active': ['FAULT'], 'usable': False},
{'raw': 5, 'active': ['PRESENT', 'FAULT'], 'usable': False},
{'raw': 6, 'active': ['STALE', 'FAULT'], 'usable': False},
{'raw': 7, 'active': ['PRESENT', 'STALE', 'FAULT'], 'usable': False},
]
actual = [describe_status(raw) for raw in range(8)]
oracle_cases_ok = True
accepted, rejected = [], []
for raw in range(256):
oracle = position_oracle(raw)
if oracle is None:
oracle_cases_ok = oracle_cases_ok and rejects(
lambda raw=raw: describe_status(raw), ValueError)
rejected.append(raw)
else:
oracle_cases_ok = oracle_cases_ok and describe_status(raw) == oracle
accepted.append(raw)
universe = frozenset((0, 1, 2))
pair_algebra_ok = True
for a in range(8):
for b in range(8):
left, right = parse_status(a), parse_status(b)
pa, pb = positions(a), positions(b)
pair_algebra_ok = pair_algebra_ok and (
int(left | right) == value_from_positions(pa | pb)
and int(left & right) == value_from_positions(pa & pb)
and int(left ^ right) == value_from_positions(pa ^ pb)
and all(type(v) is SensorStatus for v in (
left | right, left & right, left ^ right)))
complement_ok = all(
type(~parse_status(raw)) is SensorStatus
and int(~parse_status(raw)) == value_from_positions(universe - positions(raw))
for raw in range(8))
bad_ordinary = (True, False, 1.0, float('nan'), float('inf'), -float('inf'),
'1', b'1', None, [], {}, (1,))
bad_origin = (IntChild(1), SensorStatus.PRESENT, SensorStatus(0),
ForeignStatus.PRESENT, ForeignCode.PRESENT, PlainCode.PRESENT)
known_combination = parse_status(3)
kept8, kept9 = KeptStatus(8), KeptStatus(9)
addition = SensorStatus.PRESENT + SensorStatus.PRESENT
checks = {
'eight_literal_known_statuses_keep_names_and_explicit_usability_rule': actual == expected,
'all_256_unsigned_inputs_match_independent_digit_position_set_oracle_one_family': (
oracle_cases_ok and accepted == list(range(8)) and len(rejected) == 248),
'each_unknown_position_3_to_7_rejected_with_every_known_combination_one_family': all(
rejects(lambda raw=(2 ** pos + known): parse_status(raw), ValueError)
for pos in range(3, 8) for known in range(8)),
'explicit_KEEP_preserves_unknown_bits_without_making_them_known_names': (
rejects(lambda: SensorStatus(8), ValueError)
and rejects(lambda: SensorStatus(9), ValueError)
and type(kept8) is KeptStatus and int(kept8) == 8
and type(kept9) is KeptStatus and int(kept9) == 9
and [member.name for member in kept9] == ['PRESENT']),
'zero_parses_but_truthiness_is_not_the_application_usability_rule': (
type(parse_status(0)) is SensorStatus and not bool(parse_status(0))
and describe_status(0)['usable'] is False and bool(parse_status(2))
and describe_status(2)['usable'] is False),
'composites_are_valid_even_without_individual_composite_declarations': (
type(known_combination) is SensorStatus and int(known_combination) == 3
and list(known_combination) == [SensorStatus.PRESENT, SensorStatus.STALE]
and SensorStatus.PRESENT in known_combination
and SensorStatus.FAULT not in known_combination),
'all_known_complements_match_remaining_finite_position_sets': complement_ok,
'64_known_pairs_match_independent_union_intersection_symmetric_difference_one_family': pair_algebra_ok,
'integer_addition_loses_enum_type_and_is_not_set_union_for_repeated_flags': (
type(addition) is int and addition == 2
and (SensorStatus.PRESENT | SensorStatus.PRESENT) == SensorStatus.PRESENT
and int(SensorStatus.PRESENT | SensorStatus.PRESENT) == 1),
'numeric_equality_with_other_origins_is_not_nominal_boundary_validation': (
SensorStatus.PRESENT == 1 and SensorStatus.PRESENT == ForeignStatus.PRESENT
and SensorStatus.PRESENT == ForeignCode.PRESENT
and type(SensorStatus.PRESENT) is not ForeignStatus
and rejects(lambda: parse_status(ForeignStatus.PRESENT), TypeError)),
'bool_float_nonfinite_text_and_containers_rejected_without_coercion': all(
rejects(lambda value=value: parse_status(value), TypeError) for value in bad_ordinary),
'all_enum_inputs_including_own_and_int_subclasses_rejected_by_raw_input_policy': all(
rejects(lambda value=value: describe_status(value), TypeError) for value in bad_origin),
'own_nonnegative_container_bound_is_separate_from_STRICT_negative_enum_semantics': (
all(rejects(lambda value=value: parse_status(value), ValueError)
for value in (-1, -8, 256, 10 ** 1000))
and int(SensorStatus(-1)) == 7 and ~1 == -2
and rejects(lambda: parse_status(~1), ValueError)),
}
assert len(checks) == 13 and all(type(v) is bool and v for v in checks.values()), checks
return {'python': platform.python_version(), 'implementation': platform.python_implementation(),
'model': 'unitless_synthetic_status_boundary_and_application_rule',
'actual_stdlib_IntFlag_used': True, 'hardware_measurement': False,
'public_input': 'exact int 0..255 before explicit STRICT construction',
'flag_values': {'PRESENT': 1, 'STALE': 2, 'FAULT': 4},
'known_statuses': actual,
'boundary_contrast': {'strict_unknown_8': 'ValueError',
'keep_unknown_8': int(kept8), 'keep_unknown_9': int(kept9),
'keep_9_known_names': [member.name for member in kept9]},
'current_version_observations': {
'direct_enum_negative_one': int(SensorStatus(-1)),
'own_parser_rejects_negative_one': True,
'complement_PRESENT': int(~SensorStatus.PRESENT), 'plain_integer_complement_1': ~1,
'PRESENT_equal_to_integer_1': SensorStatus.PRESENT == 1,
'PRESENT_equal_to_foreign_enum_1': SensorStatus.PRESENT == ForeignStatus.PRESENT,
'duplicate_OR_value': int(SensorStatus.PRESENT | SensorStatus.PRESENT),
'duplicate_addition_value': addition, 'addition_type': type(addition).__name__},
'case_counts_not_extra_groups': {'unsigned_oracle_inputs': 256,
'unknown_position_and_known_combination_cases': 40,
'set_algebra_pairs': 64, 'complement_cases': 8},
'checks': checks}
if __name__ == '__main__':
print(json.dumps(run_example(), indent=2, allow_nan=False))
مرجع مستقل، رشتهٔ دودویی هر عددِ ازپیشمحدودشده را به مجموعهٔ جایگاهها تبدیل میکند. عضویت در مجموعهٔ جایگاههای صفر، یک و دو پذیرش نمایش را تعیین میکند؛ تنها مجموعهٔ تکعضویِ جایگاه صفر، قاعدهٔ کاربرد را میپذیرد. این مرجع از enum، تابع اصلی و ماسک بیتی آن استفاده نمیکند. تابع مرجع ابزار داخلیِ دادههای آزمون است، نه اعتبارسنجی عمومی برای شیء دلخواه یا عدد منفی.
{
"python": "3.14.5",
"implementation": "CPython",
"model": "unitless_synthetic_status_boundary_and_application_rule",
"actual_stdlib_IntFlag_used": true,
"hardware_measurement": false,
"public_input": "exact int 0..255 before explicit STRICT construction",
"flag_values": {
"PRESENT": 1,
"STALE": 2,
"FAULT": 4
},
"known_statuses": [
{
"raw": 0,
"active": [],
"usable": false
},
{
"raw": 1,
"active": [
"PRESENT"
],
"usable": true
},
{
"raw": 2,
"active": [
"STALE"
],
"usable": false
},
{
"raw": 3,
"active": [
"PRESENT",
"STALE"
],
"usable": false
},
{
"raw": 4,
"active": [
"FAULT"
],
"usable": false
},
{
"raw": 5,
"active": [
"PRESENT",
"FAULT"
],
"usable": false
},
{
"raw": 6,
"active": [
"STALE",
"FAULT"
],
"usable": false
},
{
"raw": 7,
"active": [
"PRESENT",
"STALE",
"FAULT"
],
"usable": false
}
],
"boundary_contrast": {
"strict_unknown_8": "ValueError",
"keep_unknown_8": 8,
"keep_unknown_9": 9,
"keep_9_known_names": [
"PRESENT"
]
},
"current_version_observations": {
"direct_enum_negative_one": 7,
"own_parser_rejects_negative_one": true,
"complement_PRESENT": 6,
"plain_integer_complement_1": -2,
"PRESENT_equal_to_integer_1": true,
"PRESENT_equal_to_foreign_enum_1": true,
"duplicate_OR_value": 1,
"duplicate_addition_value": 2,
"addition_type": "int"
},
"case_counts_not_extra_groups": {
"unsigned_oracle_inputs": 256,
"unknown_position_and_known_combination_cases": 40,
"set_algebra_pairs": 64,
"complement_cases": 8
},
"checks": {
"eight_literal_known_statuses_keep_names_and_explicit_usability_rule": true,
"all_256_unsigned_inputs_match_independent_digit_position_set_oracle_one_family": true,
"each_unknown_position_3_to_7_rejected_with_every_known_combination_one_family": true,
"explicit_KEEP_preserves_unknown_bits_without_making_them_known_names": true,
"zero_parses_but_truthiness_is_not_the_application_usability_rule": true,
"composites_are_valid_even_without_individual_composite_declarations": true,
"all_known_complements_match_remaining_finite_position_sets": true,
"64_known_pairs_match_independent_union_intersection_symmetric_difference_one_family": true,
"integer_addition_loses_enum_type_and_is_not_set_union_for_repeated_flags": true,
"numeric_equality_with_other_origins_is_not_nominal_boundary_validation": true,
"bool_float_nonfinite_text_and_containers_rejected_without_coercion": true,
"all_enum_inputs_including_own_and_int_subclasses_rejected_by_raw_input_policy": true,
"own_nonnegative_container_bound_is_separate_from_STRICT_negative_enum_semantics": true
}
}
از ۲۵۶ ورودی ظرف، هشت نمایش شناختهشده پذیرفته و ۲۴۸ مقدار رد میشوند. سیزده گروه نامدار، علاوه بر جدول موردانتظارِ دستی، بیتهای ناشناخته، تفاوت KEEP، صفر، ترکیب، متمم، جبر مجموعهها و نوع ورودی را میسنجند. شصتوچهار جفت و هشت متمم، حالتهای محدود همین جهان را پوشش میدهند؛ تعداد موردها را گروه جدید نمیشماریم. این آزمون محدود، ادعای صحت همهٔ کلاسهای پرچم یا ورودیهای نامحدود نیست.
۵. چهار پرسش دربارهٔ نوع و معنای وضعیت

پرسش اول: آیا صفر باید همیشه خطا باشد؟ پاسخ: خیر؛ در این نمایش، مجموعهٔ خالی مجاز است. تابع describe_status آن را با فهرست خالی و usable=False گزارش میکند. اگر رابط دیگری صفر را ممنوع بداند، آن منع قاعدهٔ اضافی همان رابط خواهد بود؛ از صفر نمیتوان سلامت یا خرابی اندازهگیری را نتیجه گرفت.
پرسش دوم: چرا True یا یک عضو enum با مقدار ۱ پذیرفته نمیشود؟ پاسخ: مرز خام، نوع دقیق int میخواهد. کد نشان میدهد PRESENT با عدد ۱ و عضو عددی یک کلاس نامرتبط برابر است، اما آن عضو از بررسی نوع عبور نمیکند. برابری عددی، بررسی هویت نوع نیست و این مرز نیز سازوکار احراز هویت یا مجوز دسترسی محسوب نمیشود.
پرسش سوم: برای ترکیب ۳ چه خروجی داریم؟ پاسخ: نامهای PRESENT و STALE و تصمیم False؛ تعریف نام جدا برای این ترکیب لازم نیست. کهنگی باعث رد قاعدهٔ کاربرد میشود، نه خطای نمایش. اگر قاعدهٔ کاربرد تغییر کند، انتظارهای همین جدول باید آگاهانه بازبینی شوند؛ تغییر نام پرچم بهتنهایی منطق تصمیم را تغییر نمیدهد.
پرسش چهارم: آیا نمایش درست، مجوز استفاده از دادهٔ فیزیکی است؟ پاسخ: خیر؛ مقدار خام فقط از قرارداد نرمافزاری محدود گذشته است. منشأ نمونه، واحد اندازهگیری، درستی پرچمِ ارسالی و رفتار سامانهٔ بعدی را نسنجیدهایم. منابع در ۲۷ مهر ۱۴۰۵ خوانده شدهاند؛ این آموزش تألیفی دربارهٔ آزمون مرز اجراست و نتیجهٔ سختافزار، سرعت یا ارزیابی امنیتی منتشر نمیکند.
منابع و مطالعهٔ بیشتر
بررسی منابع: ۲۷ مهر ۱۴۰۵. تحلیلها و پیشنهادهای اجرایی، جمعبندی نویسندهاند.

