官术网_书友最值得收藏!

Finalizing the data structure

As Linus Torvalds, the developer of Linux, once said:

"Bad programmers worry about the code. Good programmers worry about data structures and their relationships."

What he means is that well-designed data structures make the code very easy to design, maintain, and scale up. In contrast, if you start with a poor data structure, you can't make up for that, even with the best of code.

Start with a good data structure and your code will naturally be more simple, elegant, and easy to maintain.

With that in mind, let's try to decide on a suitable data structure for our program. Go back and take a look at the previous screenshot (under the Getting started section). What kind of data structure, do you think, would be needed to capture all the necessary fields of information?

Well, first of all our drum machine needs to keep information about beat patterns. So let's start by creating a list named all_patterns = [].

Now, each of the patterns within the list needs to capture information about the drum files related to the pattern: the number of units in the pattern, the BPU for the pattern, the BPM, and the buttons clicked to form the pattern.

Accordingly, we need to come up with a data structure where all_patterns is a list where each item represents a single pattern. Each pattern is then denoted by a dictionary, as follows:

{
'list_of_drum_files': a list of location of audio drum files,
'number_of_units': an integer, 'bpu': an integer,
'beats_per_minute' : an integer,'button_clicked_list' : a 2
dimensional list of boolean values where True means button is
clicked and false means button is not clicked in the pattern
}

It is very important that you get familiar with the preceding data structure definition for our drum machine. Notice that, with just this data in hand, we can define the logic to display everything that you see in the finalized drum machine.

Also notice that this data structure does not contain information about any GUI elements, such as widget information or widget states. As far as possible, we should always strive to cleanly separate the data of the backend (program logic) from the data related to the frontend (user interfaces). Our data structure here merely represents the backend but is sufficient enough to allow us to lay out the logic to determine our frontend.

The preceding data structure was what I found to be a good representation of the data at hand. There could have been an equally valid but altogether different representation of the data. There is no one correct answer to the question of data representation. However, building the representation around built-in collections of a language allows us to work with highly optimized code and is generally a good idea.  The choice of data structure directly affects the performance of an application—sometimes trivially but at other times very severely.

We modify our code accordingly (see code 3.02.py) to initialize this data structure:

    def init_all_patterns(self):
self.all_patterns = [
{
'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
'number_of_units': INITIAL_NUMBER_OF_UNITS,
'bpu': INITIAL_BPU,
'is_button_clicked_list':
self.init_is_button_clicked_list(
MAX_NUMBER_OF_DRUM_SAMPLES,
INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
)
}
for k in range(MAX_NUMBER_OF_PATTERNS)]

We also initialize is_button_clicked_list with all values set to False, as follows:

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
return [[False] * num_of_columns for x in range(num_of_rows)]

To support this structure, we define a few constants (see code 3.02.py):

MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240

Now, if you run this program, you simply see a root window—nothing different from the previous code. But internally our code is reserving memory for all the data we will need to construct our logic. We have laid a strong foundation for our program to run. Believe it or not, we have done half the job.

主站蜘蛛池模板: 永川市| 南召县| 东平县| 通化市| 铁岭市| 成安县| 文山县| 新蔡县| 兰坪| 桃源县| 张家港市| 松江区| 新河县| 双峰县| 垫江县| 凉城县| 札达县| 呼和浩特市| 临洮县| 上饶县| 珠海市| 永川市| 上林县| 姚安县| 仲巴县| 杂多县| 泽库县| 九龙坡区| 云南省| 汕头市| 合肥市| 衢州市| 突泉县| 喀喇沁旗| 娱乐| 卓资县| 白银市| 武乡县| 黄大仙区| 建水县| 郧西县|