Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions _data/mentors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2891,3 +2891,80 @@
Technology architecture & strategy; Career growth & soft skills; Navigating the job market and building a professional brand; Effective communication in technical teams
network:
- linkedin: https://www.linkedin.com/in/morar-antonela

- name: Mudit Maheshwari
disabled: false
matched: false
sort: 500
num_mentee: 4
hours: 2
type: both
index: 85
location: London, United Kingdom
position: Quality Automation Specialist, NatWest Group
bio: |
I’m a Quality Engineer with over six years of experience in test automation, passionate about building reliable, high-quality software that delivers a great user experience. I specialise in designing and maintaining automation frameworks using modern tools like Cypress, Playwright, and TypeScript, and I enjoy collaborating closely with developers to embed quality into every stage of delivery. I’m motivated by solving complex problems, mentoring others, and continuously improving processes. Outside of work, I’m deeply interested in investing and financial technology,
image: |
assets/images/mentors/mudit_maheshwari.jpeg
languages: English
availability: [9, 10]
Comment thread
khairahscorner marked this conversation as resolved.
skills:
experience: 5-7 Years
years: 7
mentee: |
Passionate , Patient , Hunger to learn
areas:
- QA
- DevOps
- Fullstack Developer
- Data Science
- Data Engineering
languages: Javascript, Java, C++, C
focus:
- Grow from beginner to mid-level
- Grow beyond senior level
- Change specialisation within IT
- Grow from mid-level to senior-level
- Switch from IC to management position
extra: |
Resume Review , Latest testing tools, Top trending tech
network:
- linkedin: https://www.linkedin.com/in/maheshwarimudit/
- medium: https://medium.com/@mudit94

- name: Anh Vu
disabled: false
matched: false
sort: 500
num_mentee: 3
hours: 3
type: both
index: 86
location: California, USA
position: Senior DevOps Engineer, Donors Choose
bio: |
I am a DevOps engineer with nearly a decade of hands-on experience specializing in infrastructure as code, with a strong focus on Terraform adoption and migration of critical production systems—including core web applications and secure bastion hosts. I have extensive experience designing and implementing scalable, containerized environments using Docker, AWS, and Kubernetes. Additionally, I’ve developed and maintained robust CI/CD pipelines using Jenkins, often building team-wide workflows and standards that have been adopted across engineering organizations.
image: |
assets/images/mentors/anh_vu.jpeg
languages: English
availability: [9, 10, 11]
skills:
experience: 7-10 Years
years: 10
mentee: |
Self starters, emotionally intelligent, women of color.
areas:
- DevOps
- Distributed Systems
- Network Engineering
- Project Management
- Security
languages: Python
focus:
- Grow from mid-level to senior-level
- Grow from beginner to mid-level
- Switch career to IT
extra: |
Prep for technical interview, resume feedback, technical mentorship, navigating interpersonal relationships in the workplace, career development.
network:
- linkedin: https://www.linkedin.com/in/anh-vu-5484bbab/
Binary file added assets/images/mentors/anh_vu.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/mentors/mudit_maheshwari.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 8 additions & 6 deletions tools/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
## How to Run Python Scripts

There are two automation scripts:
1) `automation.py`: appends new mentors in `samples/mentors.xslx` to `_data/mentor.yml`
1) `automation_add_or_update_mentors.py`: appends new mentors in `samples/mentors.xslx` to `_data/mentor.yml`

2) `download_image.py`: downloads image from a specified URL and saves in `assets/images/mentors`

3) `automation_create_mentor_spreadsheets.py`: creates spreadhseets for each longterm mentor with filenames like `WCC - Long Term - MentorName.xlsx`. All the files are saved in a folder named `Long Term Mentors`. It uses the data from `Mentorship Programme long-term Registration Form for Mentees (Responses).xlsx` sheetname `Revised Mentees`as input.
3) `meetup_import.py`: imports new upcoming events from the WCC MeetUp page using the iCal feed: https://www.meetup.com/women-coding-community/events/ical/

4) `automation_create_mentor_spreadsheets.py`: creates spreadhseets for each longterm mentor with filenames like `WCC - Long Term - MentorName.xlsx`. All the files are saved in a folder named `Long Term Mentors`. It uses the data from `Mentorship Programme long-term Registration Form for Mentees (Responses).xlsx` sheetname `Revised Mentees`as input.

### Dependencies

python 3.11 or above

### How to Execute on Mac

#### A) `automation.py`
#### A) `automation_add_or_update_mentors.py`

```shell
sh run_automation.sh
sh run_mentor_automation.sh
```
**Note:**
- Ensure to update `mentors.xslx` with the new spreadsheet containing the mentors to be added, **OR**
- adjust the `FILE_PATH_MENTORS_XLSX` parameter in [the script](run_automation.sh) to match the file path for the new spreadsheet.
- adjust the `FILE_PATH_MENTORS_XLSX` parameter in [the script](run_mentor_automation.sh) to match the file path for the new spreadsheet.
- adjust the `CURRENT_PERIOD` parameter in [the script](run_mentor_automation.sh) if running during long-term registration period (use "long-term")


#### B) `download_image.py`
Expand Down
80 changes: 56 additions & 24 deletions tools/automation.py → tools/automation_add_or_update_mentors.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import textwrap
from enum import Enum

import numpy as np
import pandas as pd
from ruamel.yaml import YAML
from ruamel.yaml.scalarstring import LiteralScalarString
Expand Down Expand Up @@ -37,6 +38,10 @@
IMAGE_FILE_PATH = "assets/images/mentors"
IMAGE_SUFFIX = ".jpeg"

# Mentorship cycle periods
LONG_TERM_REG_PERIOD = "long-term" # long-term registrations period only
DEFAULT_PERIOD = "default" # rest of the cycle, ad-hoc periods


class WriteMode(Enum):
# Create new a file
Expand Down Expand Up @@ -130,24 +135,34 @@ def get_multiline_string(long_text_arg):
multiline_str = LiteralScalarString(textwrap.dedent(long_text_arg))
return multiline_str

def get_sort(mentorship_type, num_mentee):

def is_available_for_long_term(mentorship_type):
return mentorship_type == TYPE_BOTH or mentorship_type == type_long_term[0]


def is_long_term_only(mentorship_type):
return mentorship_type == type_long_term[0]


def get_sort(mentorship_type, num_mentee, current_period):
"""
Get mentor's sort value
Rules: https://docs.google.com/document/d/1GwlleBNScHCQ3K8rgvYIB3upIr1BylgWjGR2jxwYWtI/edit?usp=sharing
"""

if mentorship_type == TYPE_BOTH or mentorship_type == type_long_term[0]:
if current_period == LONG_TERM_REG_PERIOD and is_available_for_long_term(mentorship_type):
if num_mentee > 2:
return 600
return 500
if num_mentee == 2:
return 550
return 200
if num_mentee == 1:
return 500
return 200
if mentorship_type == type_ad_hoc[0]:
#todo: (if availability == next month) then adjust the sort value:
return 100

return 10
return 100
return 10

if current_period == DEFAULT_PERIOD and is_long_term_only(mentorship_type):
return 10
return 100

def get_mentorship_type(mentorship_type_str):
"""
Expand Down Expand Up @@ -237,13 +252,24 @@ def read_yml_file(file_path):

return yml_dict

def get_num_mentee_from_row(mentor_row, default):
"""
Extract num_mentee from mentor_row, or use default if invalid.
"""
val = mentor_row.iloc[44]

return (
int(val) if pd.notna(val) and isinstance(val, (int, np.integer))
else default
)

def xlsx_to_yaml_parser(mentor_row,
mentor_index,
current_period,
mentor_disabled=False,
mentor_sort=0,
mentor_matched=False,
num_mentee=1):
num_mentee=0):
"""
Prepare mentor's excel data for yaml format
"""
Expand All @@ -259,7 +285,9 @@ def xlsx_to_yaml_parser(mentor_row,
mentor_type = get_mentorship_type(mentor_row.iloc[4])

if mentor_sort == 0:
mentor_sort = get_sort(mentor_type, num_mentee)
num_mentee = get_num_mentee_from_row(mentor_row, num_mentee)

mentor_sort = get_sort(mentor_type, num_mentee, current_period)

if not pd.isna(mentor_row.iloc[9]):
mentor_position = f"{mentor_row.iloc[8].strip()}, {mentor_row.iloc[9].strip()}"
Expand Down Expand Up @@ -329,7 +357,7 @@ def get_yml_data(yml_file_path):
return df_yml_data


def get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=0):
def get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, current_period, skip_rows=0):
"""
Read all mentors from Excel sheet:
- if mentor is in current mentors.yml, use existing values for index, disabled, sort, matched and num_mentee.
Expand All @@ -356,14 +384,16 @@ def get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=0):
if not df_yml_row.empty:
mentor = xlsx_to_yaml_parser(df_mentors.iloc[row],
df_yml_row['Index'].item(),
current_period,
df_yml_row['Disabled'].item(),
df_yml_row['Sort'].item(),
df_yml_row['Matched'].item(),
df_yml_row['Num_mentee'].item())
logging.info(f"For {mentor_name} use index, disabled and sort from mentors.yml file")
else:
mentor = xlsx_to_yaml_parser(df_mentors.iloc[row],
new_index)
new_index,
current_period)
new_index += 1
mentors.append(mentor)

Expand All @@ -372,7 +402,7 @@ def get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=0):
return mentors


def get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=1):
def get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, current_period, skip_rows=1):
"""
Read just new mentors from Excel sheet:
- start reading xlsx Mentors from the row 1 (from the date 03/04/2024)
Expand All @@ -397,7 +427,7 @@ def get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=1):
mentor_name = df_mentors.iloc[row].values[2].strip().lower()

if df_yml.loc[df_yml.Name == mentor_name].empty:
mentor = xlsx_to_yaml_parser(df_mentors.iloc[row], new_index)
mentor = xlsx_to_yaml_parser(df_mentors.iloc[row], new_index, current_period)
new_index += 1
mentors.append(mentor)

Expand All @@ -411,25 +441,27 @@ def get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=1):
def run_automation():
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

if len(sys.argv) == 5:
if len(sys.argv) == 6:
xlsx_file_path = sys.argv[1]
yml_file_path = sys.argv[2]
mode = WriteMode(sys.argv[3])
skip_rows = int(sys.argv[4])
current_period = sys.argv[3]
mode = WriteMode(sys.argv[4])
skip_rows = int(sys.argv[5])

logging.info("Params: xlsx: %s yml: %s mode: %s skip_rows: %s", xlsx_file_path, yml_file_path, mode, skip_rows)
logging.info("Params: xlsx: %s yml: %s current_period: %s mode: %s skip_rows: %s", xlsx_file_path, yml_file_path, current_period, mode, skip_rows)
else:
xlsx_file_path = "samples/mentors.xlsx"
yml_file_path = "samples/mentors.yml"
current_period = "default"
mode = WriteMode.APPEND
skip_rows = 0

logging.info("Default values: xlsx: %s yml:: %s mode: %s", xlsx_file_path, yml_file_path, mode)
logging.info("Default values: xlsx: %s yml:: %s current_period: %s mode: %s", xlsx_file_path, yml_file_path, current_period, mode)

if mode == WriteMode.APPEND:
logging.info("Appending option selected.")

list_of_mentors = get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=skip_rows)
list_of_mentors = get_new_mentors_in_yml_format(yml_file_path, xlsx_file_path, current_period, skip_rows=skip_rows)

logging.info("New Mentors size: %d", len(list_of_mentors))

Expand All @@ -439,7 +471,7 @@ def run_automation():
elif mode == WriteMode.WRITE:
logging.info("Recreate yml - Write option selected.")

list_of_mentors = get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, skip_rows=skip_rows)
list_of_mentors = get_all_mentors_in_yml_format(yml_file_path, xlsx_file_path, current_period, skip_rows=skip_rows)
write_yml_file(yml_file_path, list_of_mentors, WriteMode.WRITE)


Expand Down
4 changes: 2 additions & 2 deletions tools/download_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def download_image(url, mentor_name):

def run_automation():
if len(sys.argv) == 3:
url = sys.argv[1]
mentor_name = sys.argv[2]
mentor_name = sys.argv[1]
url = sys.argv[2]
image_path = download_image(url, mentor_name)
if image_path:
print(f"Image saved to {image_path}")
Expand Down
2 changes: 1 addition & 1 deletion tools/run_download_automation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ source myenv/bin/activate
pip install -r requirements.txt

# Enter the parameters: IMAGE_URL MENTOR_NAME
python3 download_image.py "https://media.licdn.com/dms/image/v2/D4E03AQFLzC76FGXhiQ/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1711114395505?e=1729728000&v=beta&t=P3FN1bSt0aMtt42YyJfiZCRxSqOPllf8U7O9jr2Ki_U" "Samuela Smolorz"
python3 download_image.py "Mentor Name" "image_url_here"
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ echo Installing dependencies...
pip install -r requirements.txt

setlocal
echo Enter arguments for Python script: FILE_PATH_MENTORS_XLSX FILE_PATH_MENTORS_YML MODE SKIP_ROWS
echo Example: mentors_test.xlsx mentors_test.yml a 1
echo Enter arguments for Python script: FILE_PATH_MENTORS_XLSX FILE_PATH_MENTORS_YML CURRENT_PERIOD MODE SKIP_ROWS
echo Example: mentors_test.xlsx mentors_test.yml default a 1
echo MODE: a - to append new mentors from the xlsx table to mentors.yml
echo MODE: w - to create a new mentors.yml file with all mentors that are in the xlsx table
echo SKIP_ROWS: To start XLSX in the line 1
python automation.py samples/mentors.xlsx samples/mentors.yml a 1
python automation_add_or_update_mentors.py samples/mentors.xlsx samples/mentors.yml default a 1
@echo on
7 changes: 4 additions & 3 deletions tools/run_automation.sh → tools/run_mentor_automation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ source myenv/bin/activate
# Install packages
pip install -r requirements.txt

# Enter the parameters: FILE_PATH_MENTORS_XLSX FILE_PATH_MENTORS_YML MODE SKIP_ROWS
# Example: samples/mentors.xlsx samples/mentors.yml a
# Enter the parameters: FILE_PATH_MENTORS_XLSX FILE_PATH_MENTORS_YML CURRENT_PERIOD MODE SKIP_ROWS
# Example: samples/mentors.xlsx samples/mentors.yml default a 0
# mode "a" for APPEND new mentors from the xlsx table to the existing mentors.yml
# mode "w" for WRITE all mentors from the xlsx table to mentors.yml
python3 automation.py samples/mentors.xlsx ../_data/mentors.yml a 1
# CURRENT_PERIOD: default or long-term (use long-term if currently during long-term registration period)
python3 automation_add_or_update_mentors.py samples/mentors.xlsx ../_data/mentors.yml default a 0
Binary file modified tools/samples/mentors.xlsx
Binary file not shown.
4 changes: 2 additions & 2 deletions tools/tests/automation_functional_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
import pytest
from file_utils import TOOLS_PATH
from automation import run_automation, read_yml_file, WriteMode
from automation_add_or_update_mentors import run_automation, read_yml_file, WriteMode

MENTOR_2 = "Mentor2 Name"
MENTOR_3 = "Mentor3 Name"
Expand All @@ -13,7 +13,7 @@ def test_write_mentors_skip_zero_rows(monkeypatch):
with tempfile.NamedTemporaryFile(suffix='yml', delete=False) as tmpfile:
tmp_filename = tmpfile.name

test_args = ['automation.py', os.path.join(TOOLS_PATH, "samples", "mentors.xlsx"), tmp_filename, WriteMode.WRITE, '0']
test_args = ['automation_add_or_update_mentors.py', os.path.join(TOOLS_PATH, "samples", "mentors.xlsx"), tmp_filename, "default", WriteMode.WRITE, '0']
monkeypatch.setattr(sys, 'argv', test_args)

run_automation()
Expand Down
2 changes: 1 addition & 1 deletion tools/tests/mentorship_type_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
from automation import get_mentorship_type, type_ad_hoc, type_long_term, TYPE_BOTH
from automation_add_or_update_mentors import get_mentorship_type, type_ad_hoc, type_long_term, TYPE_BOTH

class TestMentorAutomation(unittest.TestCase):
AD_HOC_1 = "Ad-Hoc Format"
Expand Down