Loading

ETH PSC Summer School MINILEAVES Hackathon

[Getting Started] ETH PSC Summer School Hackathon

This is a Baseline Code to get you started with the challenge.

dipam

This is a Baseline Code to get you started with the challenge.This is a Baseline Code to get you started with the challenge.

Baseline for ETH PSC Summer School Minileaves Hackathon

Authors : Sharada Mohanty, Gauransh Kumar

Download Necessary Packages

In [ ]:
!pip install numpy
!pip install pandas
!pip install scikit-learn
!pip install aicrowd-cli
%load_ext aicrowd.magic
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (1.21.6)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (1.3.5)
Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (1.21.6)
Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2022.2.1)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2.8.2)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: scikit-learn in /usr/local/lib/python3.7/dist-packages (1.0.2)
Requirement already satisfied: scipy>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn) (1.7.3)
Requirement already satisfied: numpy>=1.14.6 in /usr/local/lib/python3.7/dist-packages (from scikit-learn) (1.21.6)
Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn) (1.1.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn) (3.1.0)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting aicrowd-cli
  Downloading aicrowd_cli-0.1.15-py3-none-any.whl (51 kB)
     |████████████████████████████████| 51 kB 2.1 MB/s 
Collecting GitPython==3.1.18
  Downloading GitPython-3.1.18-py3-none-any.whl (170 kB)
     |████████████████████████████████| 170 kB 9.4 MB/s 
Collecting requests-toolbelt<1,>=0.9.1
  Downloading requests_toolbelt-0.9.1-py2.py3-none-any.whl (54 kB)
     |████████████████████████████████| 54 kB 2.3 MB/s 
Collecting semver<3,>=2.13.0
  Downloading semver-2.13.0-py2.py3-none-any.whl (12 kB)
Collecting rich<11,>=10.0.0
  Downloading rich-10.16.2-py3-none-any.whl (214 kB)
     |████████████████████████████████| 214 kB 43.7 MB/s 
Requirement already satisfied: toml<1,>=0.10.2 in /usr/local/lib/python3.7/dist-packages (from aicrowd-cli) (0.10.2)
Collecting python-slugify<6,>=5.0.0
  Downloading python_slugify-5.0.2-py2.py3-none-any.whl (6.7 kB)
Collecting requests<3,>=2.25.1
  Downloading requests-2.28.1-py3-none-any.whl (62 kB)
     |████████████████████████████████| 62 kB 1.5 MB/s 
Requirement already satisfied: tqdm<5,>=4.56.0 in /usr/local/lib/python3.7/dist-packages (from aicrowd-cli) (4.64.0)
Requirement already satisfied: click<8,>=7.1.2 in /usr/local/lib/python3.7/dist-packages (from aicrowd-cli) (7.1.2)
Collecting pyzmq==22.1.0
  Downloading pyzmq-22.1.0-cp37-cp37m-manylinux1_x86_64.whl (1.1 MB)
     |████████████████████████████████| 1.1 MB 43.4 MB/s 
Requirement already satisfied: typing-extensions>=3.7.4.0 in /usr/local/lib/python3.7/dist-packages (from GitPython==3.1.18->aicrowd-cli) (4.1.1)
Collecting gitdb<5,>=4.0.1
  Downloading gitdb-4.0.9-py3-none-any.whl (63 kB)
     |████████████████████████████████| 63 kB 1.1 MB/s 
Collecting smmap<6,>=3.0.1
  Downloading smmap-5.0.0-py3-none-any.whl (24 kB)
Requirement already satisfied: text-unidecode>=1.3 in /usr/local/lib/python3.7/dist-packages (from python-slugify<6,>=5.0.0->aicrowd-cli) (1.3)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.25.1->aicrowd-cli) (1.24.3)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.25.1->aicrowd-cli) (2022.6.15)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.25.1->aicrowd-cli) (2.10)
Requirement already satisfied: charset-normalizer<3,>=2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.25.1->aicrowd-cli) (2.1.1)
Collecting commonmark<0.10.0,>=0.9.0
  Downloading commonmark-0.9.1-py2.py3-none-any.whl (51 kB)
     |████████████████████████████████| 51 kB 7.4 MB/s 
Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /usr/local/lib/python3.7/dist-packages (from rich<11,>=10.0.0->aicrowd-cli) (2.6.1)
Collecting colorama<0.5.0,>=0.4.0
  Downloading colorama-0.4.5-py2.py3-none-any.whl (16 kB)
Installing collected packages: smmap, requests, gitdb, commonmark, colorama, semver, rich, requests-toolbelt, pyzmq, python-slugify, GitPython, aicrowd-cli
  Attempting uninstall: requests
    Found existing installation: requests 2.23.0
    Uninstalling requests-2.23.0:
      Successfully uninstalled requests-2.23.0
  Attempting uninstall: pyzmq
    Found existing installation: pyzmq 23.2.1
    Uninstalling pyzmq-23.2.1:
      Successfully uninstalled pyzmq-23.2.1
  Attempting uninstall: python-slugify
    Found existing installation: python-slugify 6.1.2
    Uninstalling python-slugify-6.1.2:
      Successfully uninstalled python-slugify-6.1.2
Successfully installed GitPython-3.1.18 aicrowd-cli-0.1.15 colorama-0.4.5 commonmark-0.9.1 gitdb-4.0.9 python-slugify-5.0.2 pyzmq-22.1.0 requests-2.28.1 requests-toolbelt-0.9.1 rich-10.16.2 semver-2.13.0 smmap-5.0.0
In [ ]:
%aicrowd login
Please login here: https://api.aicrowd.com/auth/SnnZYXpRRtgHer0udG64eCUvmSLURAz0nSKdt9yBRGw
API Key valid
Gitlab access token valid
Saved details successfully!

Download data

The first step is to download our train and test datasets. We will be training a classifier on the training dataset and make predictions on test dataset.

In [ ]:
#Donwload the datasets
!rm -rf data
!mkdir data
%aicrowd ds dl -c eth-psc-summer-school-minileaves-hackathon -o data
ERROR:root:Error while reading the git config, 'NoneType' object has no attribute 'config_reader'

Import packages

In [ ]:
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.neural_network import MLPClassifier
from sklearn.svm import SVC
from sklearn.metrics import f1_score,precision_score,recall_score,accuracy_score
import matplotlib.pyplot as plt

Load Data

In [ ]:
train_images_path = "data/train-images.npy" #path where data is stored
train_labels_path = "data/train-labels.npy"

train_images = np.load(train_images_path)
train_labels = np.load(train_labels_path)

# Load Class mapping
class_names = [x.strip() for x in open("data/all_classes.txt").readlines()]

Visualize the data

In [ ]:
from mpl_toolkits.axes_grid1 import ImageGrid

def random_data_sample():
    """
    Returns a random data sample from the training set
    """
    global class_name, train_images, train_labels
    random_index = np.random.randint(0, train_images.shape[0])
    # Render the image
    image_array = train_images[random_index]
    class_label = train_labels[random_index] # an integral number in [0-38)
    class_name = class_names[class_label] # a human readable class name
    return image_array, class_label, class_name

"""
Render a 7x7 grid of 49 randomly sampled images
from the training set
"""
grid_shape = (7, 7)
fig = plt.figure(figsize=(10, 10))
grid = ImageGrid(fig, 111,  # similar to subplot(111)
                 nrows_ncols=grid_shape,  # creates 2x2 grid of axes
                 axes_pad=0.1,  # pad between axes in inch.
                 )

data_samples = [random_data_sample() for _ in range(grid_shape[0] * grid_shape[1])]
for ax, data_sample in zip(grid, data_samples):
    image_array, class_label, class_name = data_sample
    ax.imshow(image_array)
    ax.axis('off')

plt.savefig("image-grid.png")

Dataset Distribution

In [ ]:
from collections import Counter

data_counter = Counter(train_labels)
unique_class_indices = data_counter.keys()

for _class_index in unique_class_indices:
    print("Class Index : ", _class_index)
    print("Class Name : ", class_names[_class_index])
    print("Number of images in the dataset : ", data_counter[_class_index])
    print("="*100)
# TODO : Add a bar plot of the distribution of the classes here
Class Index :  7
Class Name :  corn-maize-cercospora-leaf-spot-gray-leaf-spot
Number of images in the dataset :  410
====================================================================================================
Class Index :  4
Class Name :  blueberry-healthy
Number of images in the dataset :  1205
====================================================================================================
Class Index :  9
Class Name :  corn-maize-healthy
Number of images in the dataset :  925
====================================================================================================
Class Index :  29
Class Name :  tomato-early-blight
Number of images in the dataset :  806
====================================================================================================
Class Index :  20
Class Name :  potato-early-blight
Number of images in the dataset :  808
====================================================================================================
Class Index :  15
Class Name :  orange-haunglongbing-citrus-greening
Number of images in the dataset :  4422
====================================================================================================
Class Index :  37
Class Name :  tomato-tomato-yellow-leaf-curl-virus
Number of images in the dataset :  4238
====================================================================================================
Class Index :  5
Class Name :  cherry-including-sour-healthy
Number of images in the dataset :  666
====================================================================================================
Class Index :  28
Class Name :  tomato-bacterial-spot
Number of images in the dataset :  1738
====================================================================================================
Class Index :  16
Class Name :  peach-bacterial-spot
Number of images in the dataset :  1864
====================================================================================================
Class Index :  14
Class Name :  grape-leaf-blight-isariopsis-leaf-spot
Number of images in the dataset :  865
====================================================================================================
Class Index :  12
Class Name :  grape-esca-black-measles
Number of images in the dataset :  1090
====================================================================================================
Class Index :  3
Class Name :  apple-healthy
Number of images in the dataset :  1313
====================================================================================================
Class Index :  10
Class Name :  corn-maize-northern-leaf-blight
Number of images in the dataset :  794
====================================================================================================
Class Index :  24
Class Name :  soybean-healthy
Number of images in the dataset :  4087
====================================================================================================
Class Index :  33
Class Name :  tomato-septoria-leaf-spot
Number of images in the dataset :  1439
====================================================================================================
Class Index :  25
Class Name :  squash-powdery-mildew
Number of images in the dataset :  1476
====================================================================================================
Class Index :  18
Class Name :  pepper-bell-bacterial-spot
Number of images in the dataset :  799
====================================================================================================
Class Index :  23
Class Name :  raspberry-healthy
Number of images in the dataset :  297
====================================================================================================
Class Index :  31
Class Name :  tomato-late-blight
Number of images in the dataset :  1522
====================================================================================================
Class Index :  11
Class Name :  grape-black-rot
Number of images in the dataset :  953
====================================================================================================
Class Index :  32
Class Name :  tomato-leaf-mold
Number of images in the dataset :  763
====================================================================================================
Class Index :  22
Class Name :  potato-late-blight
Number of images in the dataset :  789
====================================================================================================
Class Index :  17
Class Name :  peach-healthy
Number of images in the dataset :  286
====================================================================================================
Class Index :  35
Class Name :  tomato-target-spot
Number of images in the dataset :  1117
====================================================================================================
Class Index :  6
Class Name :  cherry-including-sour-powdery-mildew
Number of images in the dataset :  820
====================================================================================================
Class Index :  34
Class Name :  tomato-spider-mites-two-spotted-spider-mite
Number of images in the dataset :  1327
====================================================================================================
Class Index :  30
Class Name :  tomato-healthy
Number of images in the dataset :  1266
====================================================================================================
Class Index :  13
Class Name :  grape-healthy
Number of images in the dataset :  337
====================================================================================================
Class Index :  19
Class Name :  pepper-bell-healthy
Number of images in the dataset :  1165
====================================================================================================
Class Index :  27
Class Name :  strawberry-leaf-scorch
Number of images in the dataset :  883
====================================================================================================
Class Index :  0
Class Name :  apple-apple-scab
Number of images in the dataset :  511
====================================================================================================
Class Index :  1
Class Name :  apple-black-rot
Number of images in the dataset :  506
====================================================================================================
Class Index :  21
Class Name :  potato-healthy
Number of images in the dataset :  120
====================================================================================================
Class Index :  36
Class Name :  tomato-tomato-mosaic-virus
Number of images in the dataset :  301
====================================================================================================
Class Index :  8
Class Name :  corn-maize-common-rust
Number of images in the dataset :  960
====================================================================================================
Class Index :  26
Class Name :  strawberry-healthy
Number of images in the dataset :  376
====================================================================================================
Class Index :  2
Class Name :  apple-cedar-apple-rust
Number of images in the dataset :  222
====================================================================================================

Split Data into Train and Validation

Now we eventually want to see how well our classifier is performing, but we dont have the test data labels with us to check. What do we do ? We split our dataset into a training set and a validation set. The idea is that we test our classifier on validation set in order to get an idea of how well our classifier works. This way we can also ensure that we dont overfit on the training dataset.

In [ ]:
X_train, X_val= train_test_split(train_images, test_size=0.2, random_state=42)
y_train, y_val= train_test_split(train_labels, test_size=0.2, random_state=42) 
## Note : Given that we use the same random state in both the splits, 
## and both `train_images` and `train_labels` have the same number of (aligned) elements, 
## the overall alignment between X_train and the corresponding Y_train will be retained.

Here we have selected the size of the testing data to be 20% of the total data. You can change it and see what effect it has on the accuracies. To learn more about the train_test_split function click here.

Define the Classifier

Now we come to the juicy part. We have fixed our data and now we train a classifier. The classifier will learn the function by looking at the inputs and corresponding outputs. There are a ton of classifiers to choose from some being Logistic Regression, SVM, Random Forests, Decision Trees, etc.
Tip: A good model doesnt depend solely on the classifier but on the features(columns) you choose. So make sure to play with your data and keep only whats important.

In [22]:
classifier = MLPClassifier(hidden_layer_sizes=(20, 20), max_iter=30)

#from sklearn.linear_model import LogisticRegression
# classifier = LogisticRegression()

## NOTE : This is definitely not the most optimal approach for this problem. 
## This code is provided to help you get started quickly, and should be treated
## as suck

We have used a very simple Multi Layer Perceptron as a classifier here and set few of the parameteres. But one can set more parameters and increase the performance. To see the list of parameters visit here.

We can also use other classifiers. To read more about sklean classifiers visit here. Try and use other classifiers to see how the performance of your model changes. Try using Logistic Regression or MLP and compare how the performance changes.

Define data pre-processors

In [ ]:
"""
Some of the models have different requirements in terms of what form of the data they can consume.

In this example, we will use 
a very simple Multi Layer Perceptron (explained further in the notebook), 
which expects a single dimensional representation for every data point. 

Hence, we will define some pre-processors which can help flatten the data,
and also normalize the data as necessary.
"""

def preprocess_X(X_array):
    assert X_array.shape[1:] == (32, 32, 3) # as the images are of the dimension 32x32x3
    
    # We normalize the whole array to a [0-1] range. As the pixel RGB values are uint8 values in the range[0, 256], 
    # we will normalize simply by dividing the whole array by 255
    X_array = X_array.astype(np.float32) / 255.0
    
    # Now, we will reshape the ndarray of shape (N, 32, 32, 3) to (N, 32*32*3), where N is the number of samples
    # present in the dataset
    X_array = X_array.reshape(X_array.shape[0], 32*32*3)
    return X_array

X_train = preprocess_X(X_train)
X_val = preprocess_X(X_val)

Train the classifier

In [24]:
classifier.fit(X_train, y_train)
/usr/local/lib/python3.7/dist-packages/sklearn/neural_network/_multilayer_perceptron.py:696: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (30) reached and the optimization hasn't converged yet.
  ConvergenceWarning,
Out[24]:
MLPClassifier(hidden_layer_sizes=(20, 20), max_iter=30)

Predict on Validation

Now we predict our trained classifier on the validation set and evaluate our model

In [ ]:
y_pred = classifier.predict(X_val)

Evaluate the Performance

We use the same metrics as that will be used for the test set.
F1 score and Log Loss are the metrics for this challenge

In [ ]:
precision = precision_score(y_val,y_pred,average='micro')
recall = recall_score(y_val,y_pred,average='micro')
accuracy = accuracy_score(y_val,y_pred)
f1 = f1_score(y_val,y_pred,average='macro')
In [ ]:
print("Accuracy of the model is :" ,accuracy)
print("Recall of the model is :" ,recall)
print("Precision of the model is :" ,precision)
print("F1 score of the model is :" ,f1)
Accuracy of the model is : 0.39832068092937656
Recall of the model is : 0.39832068092937656
Precision of the model is : 0.39832068092937656
F1 score of the model is : 0.18309288085008343

Prediction on Evaluation Set

Load Test Set

In [ ]:
test_file_path = "data/test-images.npy"
test_images = np.load(test_file_path)

Predict Test Set

The moment of truth! Predict on test set and then we can make the submission.

In [ ]:
# We first pre-process the test images, the same way we pre-process the train images
test_images = preprocess_X(test_images)

submission = classifier.predict(test_images)

Save the prediction to csv

In [ ]:
#change the header according to the submission guidelines
In [ ]:
import pandas as pd
# Saving the pandas dataframe
!rm -rf assets
!mkdir assets
submission = pd.DataFrame(submission)
submission.to_csv('assets/submission.csv',header=['class_index'],index=False)

Note: Do take a look at the submission format.The submission file should contain a header.

Make a submission using the aicrowd-cli

In [ ]:
!!aicrowd submission create -c eth-psc-summer-school-minileaves-hackathon -f assets/submission.csv
Out[ ]:
['\x1b[?25l\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m0.0%\x1b[0m • \x1b[32m0.0/31.4 KB\x1b[0m • \x1b[31m?\x1b[0m • \x1b[36m-:--:--\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m0.0%\x1b[0m • \x1b[32m0.0/31.4 KB\x1b[0m • \x1b[31m?\x1b[0m • \x1b[36m-:--:--\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m0.0%\x1b[0m • \x1b[32m0.0/31.4 KB\x1b[0m • \x1b[31m?\x1b[0m • \x1b[36m-:--:--\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m0.0%\x1b[0m • \x1b[32m0.0/31.4 KB\x1b[0m • \x1b[31m?\x1b[0m • \x1b[36m-:--:--\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[91m━━━━━━━━\x1b[0m\x1b[90m╺\x1b[0m\x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m26.1%\x1b[0m • \x1b[32m8.2/31.4 KB\x1b[0m • \x1b[31m?\x1b[0m • \x1b[36m-:--:--\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[91m━━━━━━━━━━━━\x1b[0m\x1b[90m╺\x1b[0m\x1b[90m━━━━━━━━━━\x1b[0m \x1b[35m52.3%\x1b[0m • \x1b[32m16.4/31.4 KB\x1b[0m • \x1b[31m2.5 MB/s\x1b[0m • \x1b[36m0:00:01\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[91m━━━━━━━━━━━━━━━━━━\x1b[0m\x1b[90m╺\x1b[0m\x1b[90m━━━━\x1b[0m \x1b[35m78.4%\x1b[0m • \x1b[32m24.6/31.4 KB\x1b[0m • \x1b[31m2.7 MB/s\x1b[0m • \x1b[36m0:00:01\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m32.8/31.4 KB\x1b[0m • \x1b[31m2.8 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m33.0/31.4 KB\x1b[0m • \x1b[31m2.1 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m33.0/31.4 KB\x1b[0m • \x1b[31m2.1 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m33.0/31.4 KB\x1b[0m • \x1b[31m2.1 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m33.0/31.4 KB\x1b[0m • \x1b[31m2.1 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[2K\x1b[1;34msubmission.csv\x1b[0m \x1b[90m━━━━━━━━━━━━━━━━━━━━━━\x1b[0m \x1b[35m100.0%\x1b[0m • \x1b[32m33.0/31.4 KB\x1b[0m • \x1b[31m2.1 MB/s\x1b[0m • \x1b[36m0:00:00\x1b[0m',
 '\x1b[?25h                                                    ╭─────────────────────────╮                                                     ',
 '                                                    │ \x1b[1mSuccessfully submitted!\x1b[0m │                                                     ',
 '                                                    ╰─────────────────────────╯                                                     ',
 '\x1b[3m                                                          Important links                                                           \x1b[0m',
 '┌──────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐',
 '│  This submission │ https://www.aicrowd.com/challenges/eth-psc-summer-school-minileaves-hackathon/submissions/198033              │',
 '│                  │                                                                                                               │',
 '│  All submissions │ https://www.aicrowd.com/challenges/eth-psc-summer-school-minileaves-hackathon/submissions?my_submissions=true │',
 '│                  │                                                                                                               │',
 '│      Leaderboard │ https://www.aicrowd.com/challenges/eth-psc-summer-school-minileaves-hackathon/leaderboards                    │',
 '│                  │                                                                                                               │',
 '│ Discussion forum │ https://discourse.aicrowd.com/c/eth-psc-summer-school-minileaves-hackathon                                    │',
 '│                  │                                                                                                               │',
 '│   Challenge page │ https://www.aicrowd.com/challenges/eth-psc-summer-school-minileaves-hackathon                                 │',
 '└──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘',
 "{'submission_id': 198033, 'created_at': '2022-09-12T13:14:06.115Z'}"]
In [ ]:


Comments

You must login before you can post a comment.

Execute