From 7e049fb21440c7f8ee4901f878ab54ab4c33a0b4 Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:39:25 +0530 Subject: [PATCH 1/9] Create Implement a Python program to type conversion and validation examples. --- ... a Python program to type conversion and validation examples. | 1 + 1 file changed, 1 insertion(+) create mode 100644 Implement a Python program to type conversion and validation examples. diff --git a/Implement a Python program to type conversion and validation examples. b/Implement a Python program to type conversion and validation examples. new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Implement a Python program to type conversion and validation examples. @@ -0,0 +1 @@ + From f949327818ac922d2738b12630167b0af0204454 Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:43:33 +0530 Subject: [PATCH 2/9] Delete Implement a Python program to type conversion and validation examples. --- ... a Python program to type conversion and validation examples. | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Implement a Python program to type conversion and validation examples. diff --git a/Implement a Python program to type conversion and validation examples. b/Implement a Python program to type conversion and validation examples. deleted file mode 100644 index 8b137891..00000000 --- a/Implement a Python program to type conversion and validation examples. +++ /dev/null @@ -1 +0,0 @@ - From 93b798f1402223202ff308ff4ed1aab9f9ca3c7b Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:44:49 +0530 Subject: [PATCH 3/9] Create test1 --- .../test1 | 1 + 1 file changed, 1 insertion(+) create mode 100644 Implement a Python program to type conversion and validation examples/test1 diff --git a/Implement a Python program to type conversion and validation examples/test1 b/Implement a Python program to type conversion and validation examples/test1 new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Implement a Python program to type conversion and validation examples/test1 @@ -0,0 +1 @@ + From 277b5c52a06733c4e15c528433112b64971a730d Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:46:22 +0530 Subject: [PATCH 4/9] Delete Implement a Python program to type conversion and validation examples/test1 --- .../test1 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Implement a Python program to type conversion and validation examples/test1 diff --git a/Implement a Python program to type conversion and validation examples/test1 b/Implement a Python program to type conversion and validation examples/test1 deleted file mode 100644 index 8b137891..00000000 --- a/Implement a Python program to type conversion and validation examples/test1 +++ /dev/null @@ -1 +0,0 @@ - From 6286ebe2fb16538db12e45d431b5b96a3a72093d Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:48:59 +0530 Subject: [PATCH 5/9] Create datatype conversion and validation.py --- .../datatype conversion and validation.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 Implement a Python program to type conversion and validation examples./datatype conversion and validation.py diff --git a/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py b/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py @@ -0,0 +1 @@ + From 0effd571bd5a798190175c98611dd41cda99e9ba Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:50:31 +0530 Subject: [PATCH 6/9] Add Python program for type conversion and validation Implemented a program for type conversion and validation in Python, allowing users to convert between various data types based on input. --- .../datatype conversion and validation.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py b/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py index 8b137891..8345d53f 100644 --- a/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py +++ b/Implement a Python program to type conversion and validation examples./datatype conversion and validation.py @@ -1 +1,30 @@ +a = input("Enter the value: ") +b = input("Enter the type of given datatype (int, str, float, list, tuple): ") +c = input("Which datatype do you want to convert to (int, str, float, list, tuple): ") +if b == "int": + a = int(a) +elif b == "float": + a = float(a) +elif b == "list" or b == "tuple": + a = eval(a) +elif b == "str": + a = str(a) +else: + print("Invalid original type") + +if c == "int": + a = int(a) +elif c == "float": + a = float(a) +elif c == "str": + a = str(a) +elif c == "list": + a = list(a) +elif c == "tuple": + a = tuple(a) +else: + print("Invalid target type") + +print("Converted value:", a) +print("New datatype:", type(a)) From c3f734d6ad7b19f16d441675389d16780ab386da Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:52:30 +0530 Subject: [PATCH 7/9] Create 1 --- .../1 | 1 + 1 file changed, 1 insertion(+) create mode 100644 Build a Python program to use sqlite3 to store and query records./1 diff --git a/Build a Python program to use sqlite3 to store and query records./1 b/Build a Python program to use sqlite3 to store and query records./1 new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Build a Python program to use sqlite3 to store and query records./1 @@ -0,0 +1 @@ + From ebe306863c0ad8c0c8e122519dc977d2fb7918a1 Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:54:06 +0530 Subject: [PATCH 8/9] Add files via upload --- .../app.py | 119 ++++++++++++++++++ .../model.pkl | Bin 0 -> 187257 bytes .../readme.txt | 70 +++++++++++ .../requirements.txt | 5 + .../train_model.py | 26 ++++ 5 files changed, 220 insertions(+) create mode 100644 Build a Python program to use sqlite3 to store and query records./app.py create mode 100644 Build a Python program to use sqlite3 to store and query records./model.pkl create mode 100644 Build a Python program to use sqlite3 to store and query records./readme.txt create mode 100644 Build a Python program to use sqlite3 to store and query records./requirements.txt create mode 100644 Build a Python program to use sqlite3 to store and query records./train_model.py diff --git a/Build a Python program to use sqlite3 to store and query records./app.py b/Build a Python program to use sqlite3 to store and query records./app.py new file mode 100644 index 00000000..a18d7ff3 --- /dev/null +++ b/Build a Python program to use sqlite3 to store and query records./app.py @@ -0,0 +1,119 @@ +# app.py +import os +import traceback +from functools import wraps +from flask import Flask, request, jsonify +import joblib +import numpy as np +from werkzeug.exceptions import BadRequest + +app = Flask(__name__) +MODEL_PATH = os.environ.get("MODEL_PATH", "model.pkl") + +def load_model(path): + payload = joblib.load(path) + model = payload["model"] + meta = { + "feature_names": payload.get("feature_names"), + "target_names": payload.get("target_names"), + "model_version": payload.get("model_version", "unknown") + } + return model, meta + +try: + model, MODEL_META = load_model(MODEL_PATH) + print("Model loaded:", MODEL_META) +except Exception as e: + print("Failed to load model:", e) + model, MODEL_META = None, {} + +def json_endpoint(f): + @wraps(f) + def wrapped(*args, **kwargs): + try: + return f(*args, **kwargs) + except BadRequest as br: + return jsonify({"error": "bad_request", "message": str(br.description)}), 400 + except Exception as e: + tb = traceback.format_exc() + app.logger.error(tb) + return jsonify({"error": "internal_error", "message": str(e)}), 500 + return wrapped + +@app.route("/health", methods=["GET"]) +def health(): + ok = model is not None + return jsonify({"status": "ok" if ok else "unavailable", "model_loaded": ok}), 200 if ok else 503 + +@app.route("/metadata", methods=["GET"]) +def metadata(): + return jsonify({"model_meta": MODEL_META}) + +def validate_features(features): + if not isinstance(features, list): + raise BadRequest("features must be a list of numbers") + if any(not isinstance(x, (int, float)) for x in features): + raise BadRequest("each feature must be numeric") + return np.array(features, dtype=float).reshape(1, -1) + +@app.route("/predict", methods=["POST"]) +@json_endpoint +def predict(): + payload = request.get_json(force=True) + if payload is None: + raise BadRequest("expected JSON body") + if "features" in payload: + features = payload["features"] + else: + if isinstance(payload, list): + features = payload + else: + raise BadRequest("payload must include 'features' key or be a top-level list") + X = validate_features(features) + preds = model.predict(X) + probs = None + try: + probs = model.predict_proba(X).tolist() + except Exception: + probs = None + target_name = MODEL_META.get("target_names") + pred_label = target_name[preds[0]] if target_name else int(preds[0]) + return jsonify({ + "prediction": int(preds[0]), + "label": pred_label, + "probabilities": probs, + "model_version": MODEL_META.get("model_version") + }) + +@app.route("/predict_batch", methods=["POST"]) +@json_endpoint +def predict_batch(): + payload = request.get_json(force=True) + if payload is None: + raise BadRequest("expected JSON body") + instances = payload.get("instances") + if instances is None: + if isinstance(payload, list): + instances = payload + else: + raise BadRequest("payload must include 'instances' key or be a top-level list of feature lists") + if not isinstance(instances, list) or not all(isinstance(r, list) for r in instances): + raise BadRequest("instances must be a list of feature lists") + X = np.array(instances, dtype=float) + preds = model.predict(X).tolist() + probs = None + try: + probs = model.predict_proba(X).tolist() + except Exception: + probs = None + target_name = MODEL_META.get("target_names") + labels = [target_name[int(p)] if target_name else int(p) for p in preds] + return jsonify({ + "predictions": preds, + "labels": labels, + "probabilities": probs, + "model_version": MODEL_META.get("model_version") + }) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)), debug=False) diff --git a/Build a Python program to use sqlite3 to store and query records./model.pkl b/Build a Python program to use sqlite3 to store and query records./model.pkl new file mode 100644 index 0000000000000000000000000000000000000000..69694aff245466e63c83d9c5ee0004095c6a7e9d GIT binary patch literal 187257 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 literal 0 HcmV?d00001 diff --git a/Build a Python program to use sqlite3 to store and query records./readme.txt b/Build a Python program to use sqlite3 to store and query records./readme.txt new file mode 100644 index 00000000..13fd79cd --- /dev/null +++ b/Build a Python program to use sqlite3 to store and query records./readme.txt @@ -0,0 +1,70 @@ +README - How to Run and Test the Flask Model wrapper API + +1. Install dependencies + Make sure Python 3 and pip are installed. + Then right click on the blank space of this folder and click open in terminal and type without quotes: + + "pip install -r requirements.txt" + (skip the 1st step if you already done it) + +2. to Start the Flask server + Run this command without quotes: + "python app.py" + If everything’s fine, you’ll see: + +* Running on [http://127.0.0.1:5000] or (http://127.0.0.1:5000) + +3. Check if the server is healthy + Open this link in your browser without quotes: + after "http://127.0.0.1:5000" type "/health" and + it should look like this: "http://127.0.0.1:5000/health" + It should return: + {"status": "ok", "model_loaded": true} + +4. View model metadata + To see info about the model: + [http://127.0.0.1:5000/metadata] + +5. Make a prediction + Use Postman, curl, or any REST client. + +Example (command line) without quotes: +"curl -X POST [http://127.0.0.1:5000/predict] -H "Content-Type: application/json" -d '{"features": [5.1, 3.5, 1.4, 0.2]}'" + +or if you are using powershell/cmd: +Invoke-RestMethod -Uri "http://127.0.0.1:5000/predict" ` + -Method Post ` + -ContentType "application/json" ` + -Body '{"features": [5.1, 3.5, 1.4, 0.2]}' + +Expected output: +{"prediction": 0, "label": "setosa", "probabilities": [[0.98, 0.02, 0.0]], "model_version": "1.0.0"} + +(or) + +label model_version prediction probabilities +----- ------------- ---------- ------------- +setosa 1.0.0 0 {1.0 0.0 0.0} + +6. Test batch predictions + Send multiple inputs: + curl -X POST [http://127.0.0.1:5000/predict_batch](http://127.0.0.1:5000/predict_batch) -H "Content-Type: application/json" -d '{"instances": [[5.1,3.5,1.4,0.2],[6.2,3.4,5.4,2.3]]}' + + Powershell version: + Invoke-RestMethod -Uri "http://127.0.0.1:5000/predict_batch" ` +-Method Post ` +-ContentType "application/json" ` +-Body '{"instances": [[5.1,3.5,1.4,0.2], [6.2,3.4,5.4,2.3]]}' + + +Output example: +{"predictions": [0, 2], "labels": ["setosa", "virginica"]} + +or + +labels model_version predictions probabilities +------ ------------- ----------- ------------- +{setosa, virginica} 1.0.0 {0, 2} {1.0 0.0 0.0, 0.0 0.0 1.0} + +7. Stop the server + Press Ctrl + C in the terminal. diff --git a/Build a Python program to use sqlite3 to store and query records./requirements.txt b/Build a Python program to use sqlite3 to store and query records./requirements.txt new file mode 100644 index 00000000..2e12fbe9 --- /dev/null +++ b/Build a Python program to use sqlite3 to store and query records./requirements.txt @@ -0,0 +1,5 @@ +flask +scikit-learn +joblib +numpy +gunicorn diff --git a/Build a Python program to use sqlite3 to store and query records./train_model.py b/Build a Python program to use sqlite3 to store and query records./train_model.py new file mode 100644 index 00000000..3c6646f3 --- /dev/null +++ b/Build a Python program to use sqlite3 to store and query records./train_model.py @@ -0,0 +1,26 @@ +# train_model.py +import joblib +from sklearn.datasets import load_iris +from sklearn.ensemble import RandomForestClassifier +from sklearn.model_selection import train_test_split + +def main(): + data = load_iris() + X, y = data.data, data.target + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + + clf = RandomForestClassifier(n_estimators=100, random_state=42) + clf.fit(X_train, y_train) + print("Train score:", clf.score(X_train, y_train)) + print("Test score:", clf.score(X_test, y_test)) + + joblib.dump({ + "model": clf, + "feature_names": data.feature_names, + "target_names": list(data.target_names), + "model_version": "1.0.0" + }, "model.pkl") + print("Saved model to model.pkl") + +if __name__ == "__main__": + main() From 88e21d5393565acc38bb05575dc3e55b0c88ef9c Mon Sep 17 00:00:00 2001 From: parithi029 <114157603+parithi029@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:55:02 +0530 Subject: [PATCH 9/9] Delete Build a Python program to use sqlite3 to store and query records. directory --- .../1 | 1 - .../app.py | 119 ------------------ .../model.pkl | Bin 187257 -> 0 bytes .../readme.txt | 70 ----------- .../requirements.txt | 5 - .../train_model.py | 26 ---- 6 files changed, 221 deletions(-) delete mode 100644 Build a Python program to use sqlite3 to store and query records./1 delete mode 100644 Build a Python program to use sqlite3 to store and query records./app.py delete mode 100644 Build a Python program to use sqlite3 to store and query records./model.pkl delete mode 100644 Build a Python program to use sqlite3 to store and query records./readme.txt delete mode 100644 Build a Python program to use sqlite3 to store and query records./requirements.txt delete mode 100644 Build a Python program to use sqlite3 to store and query records./train_model.py diff --git a/Build a Python program to use sqlite3 to store and query records./1 b/Build a Python program to use sqlite3 to store and query records./1 deleted file mode 100644 index 8b137891..00000000 --- a/Build a Python program to use sqlite3 to store and query records./1 +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Build a Python program to use sqlite3 to store and query records./app.py b/Build a Python program to use sqlite3 to store and query records./app.py deleted file mode 100644 index a18d7ff3..00000000 --- a/Build a Python program to use sqlite3 to store and query records./app.py +++ /dev/null @@ -1,119 +0,0 @@ -# app.py -import os -import traceback -from functools import wraps -from flask import Flask, request, jsonify -import joblib -import numpy as np -from werkzeug.exceptions import BadRequest - -app = Flask(__name__) -MODEL_PATH = os.environ.get("MODEL_PATH", "model.pkl") - -def load_model(path): - payload = joblib.load(path) - model = payload["model"] - meta = { - "feature_names": payload.get("feature_names"), - "target_names": payload.get("target_names"), - "model_version": payload.get("model_version", "unknown") - } - return model, meta - -try: - model, MODEL_META = load_model(MODEL_PATH) - print("Model loaded:", MODEL_META) -except Exception as e: - print("Failed to load model:", e) - model, MODEL_META = None, {} - -def json_endpoint(f): - @wraps(f) - def wrapped(*args, **kwargs): - try: - return f(*args, **kwargs) - except BadRequest as br: - return jsonify({"error": "bad_request", "message": str(br.description)}), 400 - except Exception as e: - tb = traceback.format_exc() - app.logger.error(tb) - return jsonify({"error": "internal_error", "message": str(e)}), 500 - return wrapped - -@app.route("/health", methods=["GET"]) -def health(): - ok = model is not None - return jsonify({"status": "ok" if ok else "unavailable", "model_loaded": ok}), 200 if ok else 503 - -@app.route("/metadata", methods=["GET"]) -def metadata(): - return jsonify({"model_meta": MODEL_META}) - -def validate_features(features): - if not isinstance(features, list): - raise BadRequest("features must be a list of numbers") - if any(not isinstance(x, (int, float)) for x in features): - raise BadRequest("each feature must be numeric") - return np.array(features, dtype=float).reshape(1, -1) - -@app.route("/predict", methods=["POST"]) -@json_endpoint -def predict(): - payload = request.get_json(force=True) - if payload is None: - raise BadRequest("expected JSON body") - if "features" in payload: - features = payload["features"] - else: - if isinstance(payload, list): - features = payload - else: - raise BadRequest("payload must include 'features' key or be a top-level list") - X = validate_features(features) - preds = model.predict(X) - probs = None - try: - probs = model.predict_proba(X).tolist() - except Exception: - probs = None - target_name = MODEL_META.get("target_names") - pred_label = target_name[preds[0]] if target_name else int(preds[0]) - return jsonify({ - "prediction": int(preds[0]), - "label": pred_label, - "probabilities": probs, - "model_version": MODEL_META.get("model_version") - }) - -@app.route("/predict_batch", methods=["POST"]) -@json_endpoint -def predict_batch(): - payload = request.get_json(force=True) - if payload is None: - raise BadRequest("expected JSON body") - instances = payload.get("instances") - if instances is None: - if isinstance(payload, list): - instances = payload - else: - raise BadRequest("payload must include 'instances' key or be a top-level list of feature lists") - if not isinstance(instances, list) or not all(isinstance(r, list) for r in instances): - raise BadRequest("instances must be a list of feature lists") - X = np.array(instances, dtype=float) - preds = model.predict(X).tolist() - probs = None - try: - probs = model.predict_proba(X).tolist() - except Exception: - probs = None - target_name = MODEL_META.get("target_names") - labels = [target_name[int(p)] if target_name else int(p) for p in preds] - return jsonify({ - "predictions": preds, - "labels": labels, - "probabilities": probs, - "model_version": MODEL_META.get("model_version") - }) - -if __name__ == "__main__": - app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)), debug=False) diff --git a/Build a Python program to use sqlite3 to store and query records./model.pkl b/Build a Python program to use sqlite3 to store and query records./model.pkl deleted file mode 100644 index 69694aff245466e63c83d9c5ee0004095c6a7e9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 187257 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 diff --git a/Build a Python program to use sqlite3 to store and query records./readme.txt b/Build a Python program to use sqlite3 to store and query records./readme.txt deleted file mode 100644 index 13fd79cd..00000000 --- a/Build a Python program to use sqlite3 to store and query records./readme.txt +++ /dev/null @@ -1,70 +0,0 @@ -README - How to Run and Test the Flask Model wrapper API - -1. Install dependencies - Make sure Python 3 and pip are installed. - Then right click on the blank space of this folder and click open in terminal and type without quotes: - - "pip install -r requirements.txt" - (skip the 1st step if you already done it) - -2. to Start the Flask server - Run this command without quotes: - "python app.py" - If everything’s fine, you’ll see: - -* Running on [http://127.0.0.1:5000] or (http://127.0.0.1:5000) - -3. Check if the server is healthy - Open this link in your browser without quotes: - after "http://127.0.0.1:5000" type "/health" and - it should look like this: "http://127.0.0.1:5000/health" - It should return: - {"status": "ok", "model_loaded": true} - -4. View model metadata - To see info about the model: - [http://127.0.0.1:5000/metadata] - -5. Make a prediction - Use Postman, curl, or any REST client. - -Example (command line) without quotes: -"curl -X POST [http://127.0.0.1:5000/predict] -H "Content-Type: application/json" -d '{"features": [5.1, 3.5, 1.4, 0.2]}'" - -or if you are using powershell/cmd: -Invoke-RestMethod -Uri "http://127.0.0.1:5000/predict" ` - -Method Post ` - -ContentType "application/json" ` - -Body '{"features": [5.1, 3.5, 1.4, 0.2]}' - -Expected output: -{"prediction": 0, "label": "setosa", "probabilities": [[0.98, 0.02, 0.0]], "model_version": "1.0.0"} - -(or) - -label model_version prediction probabilities ------ ------------- ---------- ------------- -setosa 1.0.0 0 {1.0 0.0 0.0} - -6. Test batch predictions - Send multiple inputs: - curl -X POST [http://127.0.0.1:5000/predict_batch](http://127.0.0.1:5000/predict_batch) -H "Content-Type: application/json" -d '{"instances": [[5.1,3.5,1.4,0.2],[6.2,3.4,5.4,2.3]]}' - - Powershell version: - Invoke-RestMethod -Uri "http://127.0.0.1:5000/predict_batch" ` --Method Post ` --ContentType "application/json" ` --Body '{"instances": [[5.1,3.5,1.4,0.2], [6.2,3.4,5.4,2.3]]}' - - -Output example: -{"predictions": [0, 2], "labels": ["setosa", "virginica"]} - -or - -labels model_version predictions probabilities ------- ------------- ----------- ------------- -{setosa, virginica} 1.0.0 {0, 2} {1.0 0.0 0.0, 0.0 0.0 1.0} - -7. Stop the server - Press Ctrl + C in the terminal. diff --git a/Build a Python program to use sqlite3 to store and query records./requirements.txt b/Build a Python program to use sqlite3 to store and query records./requirements.txt deleted file mode 100644 index 2e12fbe9..00000000 --- a/Build a Python program to use sqlite3 to store and query records./requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -flask -scikit-learn -joblib -numpy -gunicorn diff --git a/Build a Python program to use sqlite3 to store and query records./train_model.py b/Build a Python program to use sqlite3 to store and query records./train_model.py deleted file mode 100644 index 3c6646f3..00000000 --- a/Build a Python program to use sqlite3 to store and query records./train_model.py +++ /dev/null @@ -1,26 +0,0 @@ -# train_model.py -import joblib -from sklearn.datasets import load_iris -from sklearn.ensemble import RandomForestClassifier -from sklearn.model_selection import train_test_split - -def main(): - data = load_iris() - X, y = data.data, data.target - X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - - clf = RandomForestClassifier(n_estimators=100, random_state=42) - clf.fit(X_train, y_train) - print("Train score:", clf.score(X_train, y_train)) - print("Test score:", clf.score(X_test, y_test)) - - joblib.dump({ - "model": clf, - "feature_names": data.feature_names, - "target_names": list(data.target_names), - "model_version": "1.0.0" - }, "model.pkl") - print("Saved model to model.pkl") - -if __name__ == "__main__": - main()