EX1= r"""print("1) Image Classification on Grapevine Leaves Dataset with and without Data Augmentation.")

import os
import shutil
import random
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers, models

DATASET_ROOT = "/kaggle/input/grapevine-leaves-image-dataset/Grapevine_Leaves_Image_Dataset"

WORK_DIR = "/kaggle/working/grapevine_dataset" if "kaggle" in DATASET_ROOT else "/content/grapevine_dataset"

classes = ["Ak", "Ala_Idris", "Buzgulu", "Dimnit", "Nazli"]

if not os.path.exists(WORK_DIR):
    print("Copying dataset to writable folder...")
    shutil.copytree(DATASET_ROOT, WORK_DIR)
else:
    print("Writable dataset already exists.")

train_path = os.path.join(WORK_DIR, "train")
val_path   = os.path.join(WORK_DIR, "valid")
test_path  = os.path.join(WORK_DIR, "test")

original_structure = all(os.path.isdir(os.path.join(WORK_DIR, cls)) for cls in classes)

if original_structure:
    print("Dataset in raw form → Creating train/valid/test split...")

    os.makedirs(train_path, exist_ok=True)
    os.makedirs(val_path, exist_ok=True)
    os.makedirs(test_path, exist_ok=True)

    for cls in classes:
        os.makedirs(os.path.join(train_path, cls), exist_ok=True)
        os.makedirs(os.path.join(val_path, cls), exist_ok=True)
        os.makedirs(os.path.join(test_path, cls), exist_ok=True)

        src = os.path.join(WORK_DIR, cls)
        images = os.listdir(src)
        random.shuffle(images)

        total = len(images)
        t1 = int(total * 0.8)
        t2 = int(total * 0.9)

        train_img = images[:t1]
        val_img   = images[t1:t2]
        test_img  = images[t2:]

        for img in train_img:
            shutil.copy(os.path.join(src, img), os.path.join(train_path, cls))
        for img in val_img:
            shutil.copy(os.path.join(src, img), os.path.join(val_path, cls))
        for img in test_img:
            shutil.copy(os.path.join(src, img), os.path.join(test_path, cls))

else:
    print("train/valid/test already exist — using existing splits.")

train_no_aug = ImageDataGenerator(rescale=1./255)

train_aug = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    zoom_range=0.2,
    shear_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,
    brightness_range=[0.5,1.5]
)

val_test_gen = ImageDataGenerator(rescale=1./255)

train_gen_no_aug = train_no_aug.flow_from_directory(train_path, target_size=(128,128),
                                                    batch_size=16, class_mode="categorical")

train_gen_aug = train_aug.flow_from_directory(train_path, target_size=(128,128),
                                              batch_size=16, class_mode="categorical")

val_gen = val_test_gen.flow_from_directory(val_path, target_size=(128,128),
                                           batch_size=16, class_mode="categorical")

test_gen = val_test_gen.flow_from_directory(test_path, target_size=(128,128),
                                            batch_size=16, class_mode="categorical")

print("\nTrain:", train_gen_no_aug.samples)
print("Valid:", val_gen.samples)
print("Test :", test_gen.samples)

class_names = list(train_gen_no_aug.class_indices.keys())
batch_x, batch_y = next(train_gen_no_aug)

plt.figure(figsize=(12,4))
for i in range(5):
    plt.subplot(1,5,i+1)
    plt.imshow(batch_x[i])
    plt.title(class_names[batch_y[i].argmax()])
    plt.axis("off")
plt.show()

def create_cnn(num_classes):
    model = models.Sequential([
        layers.Conv2D(32,(3,3),activation="relu",input_shape=(128,128,3)),
        layers.MaxPooling2D(2,2),

        layers.Conv2D(64,(3,3),activation="relu"),
        layers.MaxPooling2D(2,2),

        layers.Conv2D(128,(3,3),activation="relu"),
        layers.GlobalAveragePooling2D(),

        layers.Dense(128,activation="relu"),
        layers.Dense(num_classes,activation="softmax")
    ])
    model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])
    return model

num_classes = len(class_names)
print("\nTraining WITHOUT augmentation...")
model_no_aug = create_cnn(num_classes)
history_no_aug = model_no_aug.fit(train_gen_no_aug, validation_data=val_gen, epochs=15)

test_loss_no_aug, acc_no_aug = model_no_aug.evaluate(test_gen)
print(f"\nAccuracy WITHOUT augmentation: {acc_no_aug*100:.2f}%")
print("\nTraining WITH augmentation...")
model_aug = create_cnn(num_classes)
history_aug = model_aug.fit(train_gen_aug, validation_data=val_gen, epochs=15)

test_loss_aug, acc_aug = model_aug.evaluate(test_gen)
print(f"\nAccuracy WITH augmentation: {acc_aug*100:.2f}%")
plt.figure(figsize=(10,5))
plt.plot(history_no_aug.history["val_accuracy"], label="No Augmentation")
plt.plot(history_aug.history["val_accuracy"], label="With Augmentation")
plt.title("Validation Accuracy Comparison")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()
plt.show()

print("\n================ FINAL RESULTS ================")
print(f"WITHOUT Augmentation Accuracy: {acc_no_aug*100:.2f}%")
print(f"WITH Augmentation Accuracy   : {acc_aug*100:.2f}%")
print("================================================\n")
"""
def get1():
    print(EX1)