Certainly! Below is a clean and well-structured `Feature_engineering.py` module that encapsulates all your feature engineering steps. The code follows the PEP 8 style guide, includes comprehensive docstrings for clarity, and avoids the use of global variables by passing DataFrames between functions.

```python
# Feature_engineering.py

import pandas as pd
import numpy as np

def status(feature_name: str) -> None:
    """
    Prints the status of the processed feature.

    Parameters:
    - feature_name (str): Name of the feature that has been processed.
    """
    print(f"Processed feature: {feature_name}")

def get_combined_data(train_path: str = './data/train.csv',
                      test_path: str = './data/test.csv') -> tuple:
    """
    Loads and combines the training and testing datasets.

    Parameters:
    - train_path (str): Path to the training data CSV file.
    - test_path (str): Path to the testing data CSV file.

    Returns:
    - combined (pd.DataFrame): Combined DataFrame of train and test data.
    - targets (pd.Series): Target variable from the training data.
    """
    train = pd.read_csv(train_path)
    test = pd.read_csv(test_path)

    targets = train['Survived']
    train = train.drop(['Survived'], axis=1)

    combined = pd.concat([train, test], ignore_index=True)
    combined = combined.drop(['PassengerId'], axis=1)

    return combined, targets

def extract_titles(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Extracts and maps titles from the 'Name' column to a new 'Title' feature.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with the new 'Title' feature.
    """
    title_dictionary = {
        "Mr": "Mr",
        "Mrs": "Mrs",
        "Miss": "Miss",
        "Master": "Master",
        "Dr": "Officer",
        "Rev": "Officer",
        "Col": "Officer",
        "Major": "Officer",
        "Mlle": "Miss",
        "Countess": "Royalty",
        "Ms": "Miss",
        "Lady": "Royalty",
        "Jonkheer": "Royalty",
        "Don": "Royalty",
        "Dona": "Royalty",
        "Mme": "Mrs",
        "Capt": "Officer",
        "Sir": "Royalty"
    }

    combined['Title'] = combined['Name'].apply(
        lambda name: name.split(',')[1].split('.')[0].strip()
    )
    combined['Title'] = combined['Title'].map(title_dictionary)
    combined['Title'] = combined['Title'].fillna('Other')
    status('Title')
    return combined

def fill_missing_ages(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Fills missing values in the 'Age' column using the median age
    grouped by 'Sex', 'Pclass', and 'Title'.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with missing 'Age' values filled.
    """
    grouped_median = combined.groupby(['Sex', 'Pclass', 'Title'])['Age'].median().reset_index()

    def fill_age(row):
        condition = (
            (grouped_median['Sex'] == row['Sex']) &
            (grouped_median['Title'] == row['Title']) &
            (grouped_median['Pclass'] == row['Pclass'])
        )
        age = grouped_median[condition]['Age'].values
        if len(age) > 0 and not np.isnan(age[0]):
            return age[0]
        else:
            return combined['Age'].median()  # Fallback

    combined['Age'] = combined.apply(
        lambda row: fill_age(row) if pd.isnull(row['Age']) else row['Age'], axis=1
    )
    status('Age')
    return combined

def fill_missing_fares(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Fills missing values in the 'Fare' column with the mean fare from the training set.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with missing 'Fare' values filled.
    """
    mean_fare = combined.loc[:890, 'Fare'].mean()
    combined['Fare'] = combined['Fare'].fillna(mean_fare)
    status('Fare')
    return combined

def encode_sex(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Encodes the 'Sex' column into numerical values.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with encoded 'Sex' column.
    """
    combined['Sex'] = combined['Sex'].map({'male': 1, 'female': 0})
    status('Sex')
    return combined

def encode_pclass(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Encodes the 'Pclass' column using dummy variables.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with dummy variables for 'Pclass'.
    """
    pclass_dummies = pd.get_dummies(combined['Pclass'], prefix="Pclass")
    combined = pd.concat([combined, pclass_dummies], axis=1)
    combined.drop('Pclass', axis=1, inplace=True)
    status('Pclass')
    return combined

def clean_ticket(ticket: str) -> str:
    """
    Cleans the 'Ticket' string by removing certain characters and extracting the prefix.

    Parameters:
    - ticket (str): The ticket string.

    Returns:
    - str: The cleaned ticket prefix or 'XXX' if no prefix exists.
    """
    ticket = ticket.replace('.', '').replace('/', '').split()
    ticket = list(map(str.strip, ticket))
    ticket = list(filter(lambda t: not t.isdigit(), ticket))
    return ticket[0] if len(ticket) > 0 else 'XXX'

def encode_ticket(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Encodes the 'Ticket' column by extracting prefixes and creating dummy variables.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with dummy variables for 'Ticket'.
    """
    combined['Ticket'] = combined['Ticket'].map(clean_ticket)
    tickets_dummies = pd.get_dummies(combined['Ticket'], prefix='Ticket')
    combined = pd.concat([combined, tickets_dummies], axis=1)
    combined.drop('Ticket', axis=1, inplace=True)
    status('Ticket')
    return combined

def process_family(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Creates family-related features based on 'SibSp' and 'Parch'.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with new family-related features.
    """
    combined['FamilySize'] = combined['Parch'] + combined['SibSp'] + 1
    combined['Singleton'] = combined['FamilySize'].apply(lambda s: 1 if s == 1 else 0)
    combined['SmallFamily'] = combined['FamilySize'].apply(lambda s: 1 if 2 <= s <= 4 else 0)
    combined['LargeFamily'] = combined['FamilySize'].apply(lambda s: 1 if s >= 5 else 0)
    status('Family')
    return combined

def encode_cabin(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Encodes the 'Cabin' column by extracting the first letter and creating dummy variables.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with dummy variables for 'Cabin'.
    """
    combined['Cabin'] = combined['Cabin'].fillna('Unknown')
    combined['Cabin'] = combined['Cabin'].map(lambda x: x[0] if x != 'Unknown' else 'U')
    cabin_dummies = pd.get_dummies(combined['Cabin'], prefix='Cabin')
    combined = pd.concat([combined, cabin_dummies], axis=1)
    combined.drop('Cabin', axis=1, inplace=True)
    status('Cabin')
    return combined

def encode_embarked(combined: pd.DataFrame) -> pd.DataFrame:
    """
    Encodes the 'Embarked' column using dummy variables.

    Parameters:
    - combined (pd.DataFrame): The combined DataFrame.

    Returns:
    - combined (pd.DataFrame): DataFrame with dummy variables for 'Embarked'.
    """
    combined['Embarked'] = combined['Embarked'].fillna('S')  # Assuming 'S' is the most common
    embarked_dummies = pd.get_dummies(combined['Embarked'], prefix='Embarked')
    combined = pd.concat([combined, embarked_dummies], axis=1)
    combined.drop('Embarked', axis=1, inplace=True)
    status('Embarked')
    return combined

def feature_engineering(train_path: str = './data/train.csv',
                       test_path: str = './data/test.csv') -> tuple:
    """
    Executes the complete feature engineering pipeline.

    Parameters:
    - train_path (str): Path to the training data CSV file.
    - test_path (str): Path to the testing data CSV file.

    Returns:
    - combined (pd.DataFrame): Feature-engineered DataFrame.
    - targets (pd.Series): Target variable from the training data.
    """
    # Step 1: Combine Data
    combined, targets = get_combined_data(train_path, test_path)

    # Step 2: Extract Titles
    combined = extract_titles(combined)

    # Step 3: Fill Missing Ages
    combined = fill_missing_ages(combined)

    # Step 4: Fill Missing Fares
    combined = fill_missing_fares(combined)

    # Step 5: Encode Sex
    combined = encode_sex(combined)

    # Step 6: Encode Pclass
    combined = encode_pclass(combined)

    # Step 7: Encode Ticket
    combined = encode_ticket(combined)

    # Step 8: Encode Cabin
    combined = encode_cabin(combined)

    # Step 9: Encode Embarked
    combined = encode_embarked(combined)

    # Step 10: Process Family Features
    combined = process_family(combined)

    return combined, targets

if __name__ == "__main__":
    # Example usage
    combined_data, target = feature_engineering()

    print(f"Combined Data Shape: {combined_data.shape}")
    print(combined_data.head())
```

### Explanation of the Code Structure

**Imports:**
- Only essential libraries (`pandas` and `numpy`) are imported. `matplotlib` and `seaborn` were removed as they are typically used for visualization, which is outside the scope of feature engineering.

**Status Function:**
- A helper function `status` is defined to print the status of each processed feature.

**Feature Engineering Functions:**

**Data Loading:**
- `get_combined_data` loads and combines the train and test datasets.

**Title Extraction:**
- `extract_titles` extracts titles from the 'Name' column and maps them to standardized categories.

**Missing Value Handling:**
- `fill_missing_ages` fills missing 'Age' values based on grouped medians.
- `fill_missing_fares` fills missing 'Fare' values with the mean fare from the training set.

**Encoding Categorical Variables:**
- `encode_sex` encodes the 'Sex' column.
- `encode_pclass` encodes the 'Pclass' column using dummy variables.
- `encode_ticket` extracts ticket prefixes and encodes them using dummy variables.
- `encode_cabin` extracts the first letter of the 'Cabin' column and encodes it.
- `encode_embarked` encodes the 'Embarked' column using dummy variables.

**Family Features:**
- `process_family` creates family-related features based on 'SibSp' and 'Parch'.

**Main Feature Engineering Pipeline:**
- The `feature_engineering` function orchestrates the entire pipeline by sequentially calling each feature engineering function.

**Execution Block:**
- When the script is run directly, it executes the `feature_engineering` function and prints the shape and head of the resulting DataFrame.

### Usage Instructions

**Save the Script:**
- Save the above code in a file named `Feature_engineering.py`.

**Directory Structure:**
- Ensure that your data files are located in the `./data/` directory relative to where the script is run.
- The default paths are `./data/train.csv` and `./data/test.csv`. Modify these paths if your data is located elsewhere.

**Running the Script:**
- To execute the feature engineering pipeline and see the output, run the script from the command line:
  ```sh
  python Feature_engineering.py
  ```

**Importing as a Module:**
- You can also import the `feature_engineering` function into other scripts or notebooks:
  ```python
  from Feature_engineering import feature_engineering

  combined_data, target = feature_engineering(train_path='path_to_train.csv', test_path='path_to_test.csv')
  ```

### Additional Recommendations

**Logging:**
- For more advanced status tracking, consider integrating Python's logging module instead of simple print statements.

**Error Handling:**
- Implement error handling to manage unexpected issues, such as missing columns or incorrect data types.

**Configuration:**
- Use configuration files or environment variables to manage file paths and other settings, enhancing flexibility.

**Testing:**
- Incorporate unit tests to ensure each function behaves as expected, enhancing the reliability of your feature engineering pipeline.

**Documentation:**
- Consider adding more detailed documentation or using tools like Sphinx to generate comprehensive module documentation.

This structured approach will make your feature engineering process more maintainable, reusable, and scalable.


Q- next this the modling part oky 

“III - Modeling
In this part, we use our knowledge of the passengers based on the features we created and then build a statistical model. You can think of this model as a box that crunches the information of any new passenger and decides whether or not he survives.
There is a wide variety of models to use, from logistic regression to decision trees and more sophisticated ones such as random forests and gradient boosted trees.
We'll be using Random Forests. Random Froests has proven a great efficiency in Kaggle competitions.
For more details about why ensemble methods perform well, you can refer to these posts:
http://mlwave.com/kaggle-ensembling-guide/
http://www.overkillanalytics.net/more-is-always-better-the-power-of-simple-ensembles/
Back to our problem, we now have to:
Break the combined dataset in train set and test set.
Use the train set to build a predictive model.
Evaluate the model using the train set.
Test the model using the test set and generate and output file for the submission.
Keep in mind that we'll have to reiterate on 2. and 3. until an acceptable evaluation score is achieved.
Let's start by importing the useful libraries.
In [61]:
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble.gradient_boosting import GradientBoostingClassifier
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression, LogisticRegressionCV


To evaluate our model we'll be using a 5-fold cross validation with the accuracy since it's the metric that the competition uses in the leaderboard.
To do that, we'll define a small scoring function.
In [62]:
def compute_score(clf, X, y, scoring='accuracy'):
    xval = cross_val_score(clf, X, y, cv = 5, scoring=scoring)
    return np.mean(xval)


Recovering the train set and the test set from the combined dataset is an easy task.
In [63]:
def recover_train_test_target():
    global combined
    
    targets = pd.read_csv('./data/train.csv', usecols=['Survived'])['Survived'].values
    train = combined.iloc[:891]
    test = combined.iloc[891:]
    
    return train, test, targets


In [64]:
train, test, targets = recover_train_test_target()


Feature selection
We've come up to more than 30 features so far. This number is quite large.
When feature engineering is done, we usually tend to decrease the dimensionality by selecting the "right" number of features that capture the essential.
In fact, feature selection comes with many benefits:
It decreases redundancy among the data
It speeds up the training process
It reduces overfitting
Tree-based estimators can be used to compute feature importances, which in turn can be used to discard irrelevant features.
In [65]:
clf = RandomForestClassifier(n_estimators=50, max_features='sqrt')
clf = clf.fit(train, targets)


Let's have a look at the importance of each feature.
In [66]:
features = pd.DataFrame()
features['feature'] = train.columns
features['importance'] = clf.feature_importances_
features.sort_values(by=['importance'], ascending=True, inplace=True)
features.set_index('feature', inplace=True)


In [67]:
features.plot(kind='barh', figsize=(25, 25))



As you may notice, there is a great importance linked to Title_Mr, Age, Fare, and Sex.
There is also an important correlation with the Passenger_Id.
Let's now transform our train set and test set in a more compact datasets.
In [68]:
model = SelectFromModel(clf, prefit=True)
train_reduced = model.transform(train)
print train_reduced.shape


(891L, 14L)


In [69]:
test_reduced = model.transform(test)
print test_reduced.shape


(418L, 14L)


Yay! Now we're down to a lot less features.
We'll see if we'll use the reduced or the full version of the train set.
Let's try different base models
In [70]:
logreg = LogisticRegression()
logreg_cv = LogisticRegressionCV()
rf = RandomForestClassifier()
gboost = GradientBoostingClassifier()

models = [logreg, logreg_cv, rf, gboost]


In [71]:
for model in models:
    print 'Cross-validation of : {0}'.format(model.__class__)
    score = compute_score(clf=model, X=train_reduced, y=targets, scoring='accuracy')
    print 'CV score = {0}'.format(score)
    print '****'


Cross-validation of : <class 'sklearn.linear_model.logistic.LogisticRegression'>
CV score = 0.817071431282
****
Cross-validation of : <class 'sklearn.linear_model.logistic.LogisticRegressionCV'>
CV score = 0.819318764148
****
Cross-validation of : <class 'sklearn.ensemble.forest.RandomForestClassifier'>
CV score = 0.805891969854
****
Cross-validation of : <class 'sklearn.ensemble.gradient_boosting.GradientBoostingClassifier'>
CV score = 0.830560996274
“

Q- create for each model algorithm a file and import all necessity liberties and also import the 
Feature_engineering.py for each file and then implement a robust modeling using the given algorithm oky