实现一个恋爱匹配器love compatibility calculator，练习Python基础的list语法。

## Introduction

Bob has a crush on one of his classmates in his programming class, so he wants to figure out if they are a good match. Because he took a few programming lessons, he thought he could solve this question by developing a compatibility calculator. A compatibility calculator calculates how compatible two people are based on different features, but Bob only knows his crush’s name and birthday, so that’s what he’s using.

Help Bob complete a program to calculate the love compatibility between two people based on their names and birthdays. Here is an example of how the calculator should work:

```
* Give me your first and last name:
> Bob Boba
* Give me your birthdate in the format YYYY/MM/DD:
> 2004/12/21
* Give me your crush's first and last name:
> Bobbette Bibi
* Give me your crush's birthdate in the format YYYY/MM/DD:
> 2004/02/04
* You are 74.0% compatible in love!
```

### Goals of this assignment

While developing your A2 program, you will:

- continue to apply the Function Design Recipe
- use the debugger to find out why your code isn’t working
- read and understand function docstrings
- practice writing helper functions
- work with for and while loops
- implement conditional statements
- manipulate strings using slicing and string methods
- build nested lists from raw data practice list mutation

Bob says, “Zounds, that’s a lot! What the heck are you teaching them?”

## Starter Code

For this assignment, we are giving you some files to help you get started. Please download the Assignment 2 Files and extract the zip archive, as you did with A1.

Here are the files for A2:

- compatibility_calculator.py is the file in which you will write your solution. It is the only file you will submit. Your job is to design and implement all the required functions. is the file containing the compatibility data for you to run the program. You won’t submit this file.
- compatibility_data.py
- We will test whether your code still works if we change the values defined in this file.
- Bob says that you should do that too: after you get your program working, he suggests commenting out the current values in this file (so you can recover them later) and then try different values to see if the code still works.

- a2_checker.py, checker_generic.py, and a2_pythonta.json
- Together, these are the checker program that you should use to check your code. You will not modify these files.

### Running the checker

Bob recommends that you run a2_checker.py every time you complete a function so you don’t have to fix it all at the end.

If you run it on the starter code, you’ll see a bunch of notices like this:

```
FAILED a2_checker.py::TestChecker::test_count_common_occurrences - AssertionError: count_comm on_occurrences should return a int, but returned None.
```

As you update each function, that error message will disappear.

## Problem description

The compatibility calculator consists of three sub-calculators:

- Name compatibility calculator
- Birthday compatibility calculator
- Astrological compatibility calculator

Each of these sub-calculators generate a compatibility score, and the total compatibility score of the calculator is their average value.

We have provided all function headers and the docstrings in compatibility_calculator.py. Read them carefully and make sure you understand each function’s purpose before implementing it.

## Functions you need to implement

### Task 1: Name compatibility calculator

In this task, you will implement the name compatibility calculator. You need to complete the following functions:

- count_common_occurrences(str, str) -> int - The parameters represent names, like ‘Washburn and ‘the fabulous Q’, and when you call this function it will return the number of letters from the first one that appear in the second one, ignoring case. Spaces, punctuation, Marchmutt’ and digits are of course not alphabetic.
- See the docstring for more details, including examples.
- Hint: use a string method that tell you whether a character is alphabetic and another string method that gives you a lowercase or uppercase version of a string.

- get_name_compatibility(str, str) -> int - This function returns the name compatibility between two names in the input. According to Bob’s rules, this should be calculated by checking how many letters in the first person’s name occur in the second person’s name, and adding this to how many letters in the second one occur in the first one (all ignoring case), then dividing this sum by the total number of alphabetic characters in the two names combined, and multiplying this by 100.
- See the docstring for more details.
- Hint: use the count_common_occurrences function as a helper.

## Task 2: Birthday compatibility calculator

In this task, you will implement the birthday compatibility calculator.

To calculate the compatibility between two birthdays, you need to get their numerological numbers and decide whether they are compatible or not.

### Task 2.1: Dealing with the birthdates

For your first task, you will complete three helper functions for dealing with the date input:

- extract_year(str) -> int
- extract_month(str) -> int
- extract_day(str) -> int
- The description and examples have been provided for function extract_year. Follow the TODO instructions in these functions to complete them.

### Task 2.2: Calculate the numerological number of a birthday

For this task, Bob completed function get_bday_numerology_num, but it relies on a helper function, get_numerological_root, which he never got around to figuring out. So you’re going to have to do it:

- get_numerological_root(int) -> int - This function should return the numerological root number of the input. The root number is found by adding the digits in the parameter value together until you are left with either a single digit or one of the two Special Numbers: 11 or 22.
- For example, the numerological root number of 1998 is 9. This is because 1 + 9 + 9 + 8 = 27. Since 27 has two digits and is not a Special Number, we repeat the summing process: 2 + 7 = 9. 9 has one digit, so it is the numerological root number of 1998.
- See the docstring for more details.
- Hint: You can turn the parameter value into a string to deal with it, or you can use operators % and //. The expression n % 10 gives you the last digit in a number n , and n // 10 removes the last digit in n.

### Task 2.3: Calculate the compatibility between two numerological numbers

Go look at the NUM_COMPATIBILITY_DATA list in compatibility_data.py. Do this now, before reading the rest of the handout. The list shows whether two numbers are “compatible”, according to Bob. Make sure you read and understand the comment and the data.

For this task, you will complete the following functions:

- build_numerology_list(list[str]) -> list[list[int]] - Given a list of strings where each item is a string formatted as in NUM_COMPATIBILITY_DATA , this function builds and returns a numerology list that contains the same data but in a different format.
- Read the docstring for details and make sure you understand the examples.
- Hint: you can use method list.sort() or the built-in sorted function.
- Hint: you’ll need to sort the main list. list.sort() and sorted will both do this by comparing the first items:

```
>>> list_of_lists = [[2, 3, 4], [1, 5, 6], [3, 0, 0]]
>>> list_of_lists.sort()
>>> list_of_lists [[1, 5, 6], [2, 3, 4], [3, 0, 0]]
```

- get_numerology_compatibility(int, int, list) -> int - Given the numerological numbers of two birthdays and a numerology list that you build from NUM_COMPATIBILITY_DATA, this function returns the compatibility of two birthdays based on their numerological numbers.
- Read the docstring for details and make sure you understand the examples.
- Note: The first numerological number is not guaranteed to appear in NUM_COMPATIBILITY_DATA. You should return MID_COMPATIBILITY in this situation.

## Task 3: Astrological compatibility calculator

In this task, you will implement the astrological (zodiac) sign compatibility calculator.

### Task 3.1: Astrological sign of a birthday

Go read about SIGN_DATA in the starter code. Make sure you understand the comment and the data.

For this task, you will complete the following functions:

- build_sign_data_list(list[str]) -> list[list] - Convert a list formatted like SIGN_DATA to a list of lists.
- Read the docstring for details and make sure you understand the examples.
- Later, you will call this function to convert SIGN_DATA to a nested list.

- find_astrological_sign(list[list], int, int) -> str - Given sign data, a birth month, and a birth day, this function returns the sign of a person born on the given day in the given month.
- Read the docstring for details and make sure you understand the examples.
- Note: All start and end dates are inclusive.

- get_sign_group(list[list], str) -> int - This function returns the group number of the given sign using the sign data.
- Read the docstring for details and make sure you understand the examples.

### Task 3.2: Astrological compatibility of two birthdays

For this task, you will complete a helper function used to find the astrological compatibility of two birthdays. The compatibility between signs of two birthdays is calculated based on the sign groups they belong to.

Complete the following helper function:

- find_astrological_compatibility(int, int) -> int - This function returns an integer representing how compatible two sign groups are.
- Read the docstring for details and make sure you understand the examples.

## Task 4: Putting it all together

Finally, you can finish the main compatibility calculator function, calculate_love_score.

The compatibility score between two people is their name compatibility plus the numerology compatibility of their birthdays plus the sign compatibility of the birthdays, all divided by three.

- As always, read the docstring for details and make sure you understand the examples.

## Submission instructions

- Log in to MarkUs.
- Submit the file compatibility_calculator.py . No other files need to be submitted. We strongly recommend that you submit early and often. We will grade the latest version you submit within the permitted submission period.
- Be sure to run the tests we’ve provided within MarkUs frequently, and always one last time before the due date. This will make sure that you didn’t accidentally submit the wrong version of your code, or worse yet, the starter code!