<jupyter_start><jupyter_text>Chapter 2: Building Abstractions with Data  2.1 Introductionnative data type1. There are expressions that evaluate to values of native types, called literals.2. There are built-in functions and operators to manipulate values of native types.*Int, float, complex** int objects represent integers exactly* float objects can represent a wide range of fractional numbers<jupyter_code>type(1)<jupyter_output><empty_output><jupyter_text>2.2 Data Abstraction Some functions enforce abstract barrier. These functions are called by a higher level and implemented using a lower level of abstraction.An abstraction barrier violation occurs whenever a part of the program that can use a higher level function instead uses a function in a lower level. For example, a function that computes the square of a rational number is best implemented in terms of mul_rational, which does not assume anything about the implementation of a rational number.**Abstraction barrier makes program easier to maintain and debug.**In general, we can express abstract data using a collection of selectors and constructors, together with some behavior conditions.   2.3 Sequences Sequences are not instances of a particular built-in type or abstract data representation, but instead a collection of behaviors that are shared among several different types of data.* Length* Element selection* Membership* SlicingThis underscore is just another name in the environment as far as the interpreter is concerned, but has a conventional meaning among programmers that indicates the name will not appear in any future expressions.The general form of list comprehension is```python[ for  in  if ]```* Map* Filter* AggregationHigher order functions* apply to all (map)* kepp if (filter)* reduceStringString membership check is for substringPython does not have a separate character type<jupyter_code>def width(area, height):
    assert area % height == 0
    return area // height
def perimeter(width, height):
    return 2 * width + 2 * height
def minimum_perimeter(area):
    heights = divisors(area)
    perimeters = [perimeter(width(area, h), h) for h in heights]
    return min(perimeters)
def divisors(n):
    return [1] + [x for x in range(2, n) if n % x == 0]
area = 80
width(area, 5)
minimum_perimeter(area)
'您好'
import this
s = """UW-Madison
is great!"""
s<jupyter_output><empty_output><jupyter_text>**Tree**The tree is a fundamental data abstraction that imposes regularity on how hierarchical values are structured and manipulated.**This chapter is unfinished!**  2.4 Mutable DataEffective programming also requires organizational principles that can guide us in formulating the overall design of a program. In particular, we need strategies to help us structure large systems to be modular, meaning that they divide naturally into coherent parts that can be separately developed and maintained. One powerful technique for creating modular programs is to incorporate data that may change state over time.<jupyter_code>"1234".isnumeric()
"AbC".swapcase()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.056818181818181816, 'fraction_numerical': 0.008116883116883116, 'mean_word_length': 5.445606694560669, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '150154', 'license': 'MIT', 'n_tokens_mistral': 768, 'n_tokens_neox': 720, 'n_words': 403, 'path': 'Chapter-2.ipynb', 'repo_name': 'zhangyaqi1989/Structure-and-Interpretation-of-Computer-Programs', 'size': '3080'}