diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..69d9d27
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+node_modules
+npm-debug.log
+dist
+.git
+.gitignore
+.DS_Store
+*.log
diff --git a/.github/workflows/deploy-containerapp.yml b/.github/workflows/deploy-containerapp.yml
new file mode 100644
index 0000000..50b3157
--- /dev/null
+++ b/.github/workflows/deploy-containerapp.yml
@@ -0,0 +1,42 @@
+name: Deploy Container App
+
+on:
+ push:
+ branches: [main]
+
+permissions:
+ contents: read
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Azure Login
+ uses: azure/login@v2
+ with:
+ client-id: ${{ secrets.AZURE_CLIENT_ID }}
+ tenant-id: ${{ secrets.AZURE_TENANT_ID }}
+ subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
+ client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
+
+ - name: Build and push image
+ run: |
+ ACR=${{ secrets.ACR_NAME }}
+ IMAGE="$ACR.azurecr.io/resume-web:${{ github.sha }}"
+ az acr login --name "$ACR"
+ docker build -f Dockerfile.chat -t "$IMAGE" .
+ docker push "$IMAGE"
+ echo "IMAGE=$IMAGE" >> $GITHUB_ENV
+
+ - name: Update Container App
+ run: |
+ az containerapp update \
+ --name ${{ secrets.CONTAINERAPP_NAME }} \
+ --resource-group ${{ secrets.RESOURCE_GROUP }} \
+ --image "$IMAGE" \
+ --set-env-vars \
+ AZURE_OPENAI_API_KEY=${{ secrets.AZURE_OPENAI_API_KEY }} \
+ AZURE_OPENAI_ENDPOINT=${{ secrets.AZURE_OPENAI_ENDPOINT }}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..61fe821
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,17 @@
+FROM node:20-alpine AS builder
+
+WORKDIR /app
+
+COPY package.json package-lock.json ./
+RUN npm ci
+
+COPY . .
+RUN npm run build
+
+FROM nginx:alpine
+
+COPY --from=builder /app/docs /usr/share/nginx/html
+
+EXPOSE 80
+
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/Dockerfile.chat b/Dockerfile.chat
new file mode 100644
index 0000000..575d44c
--- /dev/null
+++ b/Dockerfile.chat
@@ -0,0 +1,24 @@
+FROM node:20-alpine AS build
+
+WORKDIR /app
+
+COPY package.json package-lock.json ./
+RUN npm ci
+
+COPY tailwind.css postcss.config.js tailwind.config.js ./
+COPY docs ./docs
+RUN npm run build
+
+FROM python:3.11-slim
+
+WORKDIR /app
+
+COPY cv_chat/requirements.txt ./
+RUN pip install --no-cache-dir -r requirements.txt
+
+COPY cv_chat ./cv_chat
+COPY --from=build /app/docs ./docs
+
+ENV PORT=8080
+
+CMD ["gunicorn", "-w", "2", "-b", "0.0.0.0:8080", "cv_chat.app:app"]
diff --git a/README.md b/README.md
index 113c89a..3fe7c43 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,98 @@ Only generate CSS that is used on the page, which results in a much smaller file
npm run build
```
+Tutorial: What Was Done
+---------
+
+This project was updated and deployed as a static résumé site. Below is a concise walkthrough of the changes and deployment flow so you can repeat it.
+
+### 1) Update the content
+
+- Edit `docs/index.html` and replace the template content with your CV details.
+- Keep the overall structure (sections, headers, list items) so the layout stays consistent.
+
+### 2) Tailwind v4 + PostCSS fixes
+
+Tailwind v4 moved its PostCSS plugin to a separate package. The build pipeline was adjusted accordingly:
+
+```
+npm install @tailwindcss/postcss
+```
+
+In `postcss.config.js`, swap the Tailwind plugin for the new one and pass the config path:
+
+```
+require("@tailwindcss/postcss")({
+ config: "./tailwind.config.js"
+})
+```
+
+In `tailwind.css`, use the v4 import style:
+
+```
+@import "tailwindcss";
+```
+
+### 3) Two-column layout
+
+To force two columns on all screen sizes, use `col-count-2` (without the `md:` prefix) on the column container in `docs/index.html`:
+
+```
+
+```
+
+### 4) Replace deprecated CSS
+
+Autoprefixer warns about `color-adjust` being deprecated. Update this in `tailwind.css`:
+
+```
+print-color-adjust: exact !important;
+```
+
+### 5) Docker production container
+
+A production Docker image builds the CSS and serves the site via Nginx.
+
+```
+docker build -t universal-resume .
+docker run --rm -p 8080:80 universal-resume
+```
+
+### 6) Azure Static Website deployment
+
+This setup uses Azure Storage Static Website hosting.
+
+Install Azure CLI (Windows):
+
+```
+https://aka.ms/installazurecliwindows
+```
+
+Login (PowerShell needs the `&` call operator):
+
+```
+& "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" login --use-device-code
+```
+
+Then create resources and upload:
+
+```
+$rg = "universal-resume-rg"
+$loc = "germanywestcentral"
+$sa = "resumestatic" + (Get-Random -Maximum 99999)
+
+& "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" group create --name $rg --location $loc
+& "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" storage account create --name $sa --resource-group $rg --location $loc --sku Standard_LRS --kind StorageV2 --allow-blob-public-access true
+& "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" storage blob service-properties update --account-name $sa --static-website --index-document index.html --404-document index.html
+
+$web = & "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" storage account show --name $sa --resource-group $rg --query "primaryEndpoints.web" -o tsv
+
+$key = & "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" storage account keys list --account-name $sa --resource-group $rg --query "[0].value" -o tsv
+& "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" storage blob upload-batch --account-name $sa --account-key $key --destination '$web' --source .\docs
+
+$web
+```
+
Starting Point
---------
diff --git a/cv_chat/.gitattributes b/cv_chat/.gitattributes
new file mode 100644
index 0000000..dfe0770
--- /dev/null
+++ b/cv_chat/.gitattributes
@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
diff --git a/cv_chat/.gitignore b/cv_chat/.gitignore
new file mode 100644
index 0000000..930e1b2
--- /dev/null
+++ b/cv_chat/.gitignore
@@ -0,0 +1,17 @@
+
+# dependencies
+/.ipynb_checkpoints
+/.pnp
+.pnp.js
+
+# misc
+.DS_Store
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
\ No newline at end of file
diff --git a/cv_chat/andrei_context.txt b/cv_chat/andrei_context.txt
new file mode 100644
index 0000000..685652c
--- /dev/null
+++ b/cv_chat/andrei_context.txt
@@ -0,0 +1,53 @@
+Name: Andrei Sirazitdinov
+Location: Mannheim, Germany
+Contact: dyh@list.ru | +49 176 47699707
+
+About:
+- Ph.D. in Computer Science
+- University of Heidelberg | Data Science, ML, AI, Computer Vision
+- As a researcher, I was focused on causal inference and individualized treatment effect estimation with deep learning. I also worked on explainable AI for healthcare and vision tasks. Permanent residency and full work authorization in Germany. Open to relocation.
+
+Research interests:
+- Causal inference, individualized treatment assignment, explainable ML
+- Built and evaluated deep learning models (MLPs, GANs, VAEs, GNNs) in TensorFlow, Keras, and PyTorch for healthcare decision support, privacy, and explainability.
+
+Experience:
+- University of Heidelberg, Germany (Apr 2020 – Oct 2025) — Ph.D. Candidate
+ - Individualized treatment assignment with MLPs, GANs, VAEs, and GNNs in TensorFlow/Keras.
+ - Pain patient treatment strategies using K-NN clustering and XGBoost with RCT validation.
+ - Explainable pathology patch classification with prototype learning and decision trees in PyTorch.
+ - Digital twin models using stable diffusion for patient data privacy in PyTorch.
+ - Dropout prediction model for cancer patients achieving 80% precision in TensorFlow.
+- National Institute of Informatics, Japan (Oct 2018 – Apr 2019) — Research Intern
+ - Computer vision algorithm for long-term video prediction using PyTorch.
+- Irkutsk Branch of MSTUCA, Russia (Oct 2014 – Jul 2015) — Student Assistant
+ - Built a multi-camera system to capture helicopter panel data and populate digital tables automatically.
+
+Education:
+- Ph.D. in Computer Science — University of Heidelberg, Germany (2020 – 2025)
+- M.Sc. in Visual Computing — Saarland University, Germany (2016 – 2019)
+- B.Sc. in Applied Informatics and Mathematics — Irkutsk State University, Russia (2012 – 2016)
+- High School — Irkutsk, Russia (2010 – 2012)
+
+Projects:
+- Trading Bots (Python) — WebSocket API | Docker | GitHub Actions
+- Local ChatGPT Clone — Streamlit | OpenAI API | SQLite
+- Databricks Integration — Centralized storage for chats and user authentication
+
+Skills:
+- ML/AI: TensorFlow, PyTorch, Scikit-learn, Keras
+- Data tools: Pandas, NumPy
+- Tools and platforms: Python, SQL, R, Docker, Kubernetes, MLflow, Azure (beginner), Git, Linux, Windows
+
+Languages:
+- English (Fluent speaking, reading, and writing)
+- German (B1 certificate, completed C1 courses)
+- Russian (Native)
+
+Selected publications:
+- A. Sirazitdinov et al., "Graph Neural Networks for Individual Treatment Effect Estimation," IEEE Access, 2024.
+- A. Sirazitdinov et al., "Review of Deep Learning Methods for Individual Treatment Effect Estimation with Automatic Hyperparameter Optimization," TechRxiv, 2022.
+
+Git Repos:
+- https://github.com/dyh1265/Causal-Inference-Library — Causal inference library for GNN-TARNet and related models; includes notebooks and code for the GNN-ITE paper.
+- https://github.com/dyh1265/PerPain-allocation — PerPain patient allocation system with two approaches: an R Shiny clustering app and Python ML models (TARnet, GNN-TARnet, GAT-TARnet, T-Learner) for individualized treatment recommendations.
diff --git a/cv_chat/app.py b/cv_chat/app.py
new file mode 100644
index 0000000..a62345e
--- /dev/null
+++ b/cv_chat/app.py
@@ -0,0 +1,124 @@
+import os
+import re
+from html import unescape
+from html.parser import HTMLParser
+from pathlib import Path
+
+import dotenv
+from flask import Flask, request, send_from_directory
+from openai import AzureOpenAI
+
+dotenv.load_dotenv()
+
+BASE_DIR = Path(__file__).resolve().parent
+DOCS_DIR = BASE_DIR.parent / "docs"
+
+app = Flask(__name__, static_folder=str(DOCS_DIR), static_url_path="")
+
+client = AzureOpenAI(
+ api_key=os.getenv("AZURE_OPENAI_API_KEY"),
+ api_version="2024-02-15-preview",
+ azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT")
+)
+
+
+
+context_path = BASE_DIR / "andrei_context.txt"
+
+
+class _CVTextParser(HTMLParser):
+ def __init__(self):
+ super().__init__()
+ self._chunks = []
+ self._skip = False
+
+ def handle_starttag(self, tag, attrs):
+ if tag in {"script", "style"}:
+ self._skip = True
+ if tag in {"h1", "h2", "h3", "p", "li"}:
+ self._chunks.append("\n")
+
+ def handle_endtag(self, tag):
+ if tag in {"script", "style"}:
+ self._skip = False
+ if tag in {"h1", "h2", "h3", "p", "li"}:
+ self._chunks.append("\n")
+
+ def handle_data(self, data):
+ if self._skip:
+ return
+ text = data.strip()
+ if text:
+ self._chunks.append(text)
+
+ def text(self):
+ raw = " ".join(self._chunks)
+ normalized = re.sub(r"[ \t]+", " ", raw)
+ normalized = re.sub(r"\n{2,}", "\n", normalized)
+ return normalized.strip()
+
+
+def build_context_from_cv(cv_path: Path, extra_context: str) -> str:
+ if not cv_path.exists():
+ return extra_context
+ parser = _CVTextParser()
+ parser.feed(cv_path.read_text(encoding="utf-8"))
+ cv_text = unescape(parser.text())
+ cv_text = re.sub(r"[ \t]+\n", "\n", cv_text)
+
+ git_block = ""
+ if "Git Repos:" in extra_context:
+ parts = extra_context.split("Git Repos:", 1)
+ git_block = "Git Repos:\n" + parts[1].strip()
+
+ if git_block:
+ return f"{cv_text}\n\n{git_block}"
+ return cv_text
+
+
+if context_path.exists():
+ raw_context = context_path.read_text(encoding="utf-8").strip()
+else:
+ raw_context = ""
+
+andrei_context = build_context_from_cv(DOCS_DIR / "index.html", raw_context)
+
+conversation = [
+ {
+ "role": "system",
+ "content": (
+ "You are a concise assistant that only answers questions about Andrei Sirazitdinov's skills, competencies, prrojects, and background. "
+ "Reply in short bullet points (no bold). If the question is not about Andrei's skills, competencies, projects, and background, say you can only answer "
+ "questions about his skills, competencies, projects, and background and ask the user to rephrase."
+ + (f"\n\nContext about Andrei:\n{andrei_context}" if andrei_context else "")
+ ),
+ }
+]
+
+@app.route("/")
+def index():
+ return send_from_directory(DOCS_DIR, "index.html")
+
+
+@app.route("/")
+def static_files(filename):
+ return send_from_directory(DOCS_DIR, filename)
+
+@app.route("/chat", methods=["POST"])
+def chat():
+ user_input = request.json.get("message")
+ conversation.append({"role": "user", "content": user_input})
+
+ response = client.chat.completions.create(
+ model="gpt-5.2-chat",
+ messages=conversation
+ )
+
+ reply = response.choices[0].message.content
+ conversation.append({"role": "assistant", "content": reply})
+
+ return reply
+
+if __name__ == '__main__':
+ port = int(os.getenv("PORT", "8080"))
+ app.run(host="0.0.0.0", port=port, debug=False)
diff --git a/cv_chat/requirements.txt b/cv_chat/requirements.txt
new file mode 100644
index 0000000..1294f24
--- /dev/null
+++ b/cv_chat/requirements.txt
@@ -0,0 +1,4 @@
+flask==3.0.2
+python-dotenv==1.0.1
+openai==1.59.7
+gunicorn==22.0.0
diff --git a/cv_chat/static/index.css b/cv_chat/static/index.css
new file mode 100644
index 0000000..a21a891
--- /dev/null
+++ b/cv_chat/static/index.css
@@ -0,0 +1,150 @@
+h1 {
+ text-align: center;
+ margin: 50px;
+}
+
+div {
+ position: relative;
+ display: block;
+ unicode-bidi: isolate;
+}
+
+.rsc-container {
+ background: rgb(245, 248, 251);
+ border-radius: 10px;
+ box-shadow: rgba(0, 0, 0, 0.15) 0px 12px 24px 0px;
+ font-family: monospace;
+ overflow: hidden;
+ position: relative;
+ inset: initial;
+ width: 350px;
+ height: 520px;
+ z-index: 999;
+ margin: auto;
+ transform: scale(1);
+ transform-origin: right bottom;
+ transition: transform 0.3s ease 0s;
+}
+
+.rsc-header {
+ -webkit-box-align: center;
+ align-items: center;
+ background: rgb(110, 72, 170);
+ color: rgb(255, 255, 255);
+ display: flex;
+ fill: rgb(255, 255, 255);
+ height: 56px;
+ -webkit-box-pack: justify;
+ justify-content: space-between;
+ padding: 0px 10px;
+}
+
+.rsc-header-title {
+ margin: 0px;
+ font-size: 16px;
+}
+
+.rsc-content {
+ height: calc(408px);
+ overflow-y: scroll;
+ margin-top: 2px;
+ padding-top: 6px;
+}
+
+.rsc-ts-bot {
+ align-items: flex-start;
+ display: flex;
+ -webkit-box-pack: start;
+ justify-content: flex-start;
+ height: auto;
+}
+
+.rsc-ts-user {
+ align-items: flex-start;
+ display: flex;
+ -webkit-box-pack: end;
+ justify-content: flex-start;
+}
+
+.rsc-ts-bot {
+ animation: 0.3s ease 0s 1 normal forwards running Lmuha;
+ background: rgb(110, 72, 170);
+ border-radius: 18px 18px 18px 0px;
+ box-shadow: rgba(0, 0, 0, 0.15) 0px 1px 2px 0px;
+ color: rgb(255, 255, 255);
+ font-size: 14px;
+ max-width: 75%;
+ margin: 0px 0px 10px 10px;
+ overflow: hidden;
+ position: relative;
+ padding: 12px;
+ transform-origin: left bottom;
+}
+
+.rsc-ts-user {
+ animation: 0.3s ease 0s 1 normal forwards running Lmuha;
+ background: rgb(255, 255, 255);
+ border-radius: 18px 18px 0px 18px;
+ box-shadow: rgba(0, 0, 0, 0.15) 0px 1px 2px 0px;
+ color: rgb(0, 0, 0);
+ font-size: 14px;
+ width: auto;
+ max-width: 75%;
+ margin: 0px 10px 10px auto;
+ overflow: hidden;
+ position: relative;
+ padding: 12px;
+ transform-origin: right bottom;
+}
+
+.rsc-ts-image {
+ border-radius: 50%;
+ margin-right: 10px;
+}
+
+.rsc-footer {
+ position: relative;
+}
+
+.rsc-input {
+ border-width: 1px 0px 0px;
+ border-right-style: initial;
+ border-bottom-style: initial;
+ border-left-style: initial;
+ border-right-color: initial;
+ border-bottom-color: initial;
+ border-left-color: initial;
+ border-image: initial;
+ border-radius: 0px 0px 10px 10px;
+ border-top-style: solid;
+ border-top-color: rgb(238, 238, 238);
+ box-shadow: none;
+ box-sizing: border-box;
+ font-size: 16px;
+ opacity: 0.5;
+ outline: none;
+ padding: 16px 52px 16px 10px;
+ width: 100%;
+ appearance: none;
+}
+
+.rsc-submit-button {
+ background-color: transparent;
+ border: 0px;
+ border-bottom-right-radius: 10px;
+ box-shadow: none;
+ cursor: default;
+ fill: rgb(74, 74, 74);
+ opacity: 0.5;
+ outline: none;
+ padding: 14px 16px 12px;
+ position: absolute;
+ right: 0px;
+ top: -5px;
+}
+
+.chat-response {
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+}
\ No newline at end of file
diff --git a/cv_chat/templates/index.html b/cv_chat/templates/index.html
new file mode 100644
index 0000000..249c022
--- /dev/null
+++ b/cv_chat/templates/index.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+ Fashion Chatbot
+
+
+
+
+
+
+
+
Fashion Chatbot
+
+
+
+
Chat
+
+
+
+
+
+
Hello!! How can I help you today.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
index ceedba5..3338513 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,17 +1,17 @@
-
+
-
-
-
+
+
+
- Marko Marković — Resume
+ Andrei Sirazitdinov — Resume
@@ -22,19 +22,19 @@
-
-
M
-
M
+
A
+
S
- Marko Marković
+ Andrei Sirazitdinov
-
+
@@ -48,16 +48,15 @@
- User Interface Designer
+ Ph.D. in Computer Science
- Since 2010
+ University of Heidelberg | Data Science, ML, AI, Computer Vision
- Minimal and formal résumé website template for print, mobile, and desktop. The proportions are
- the same on the screen and paper. Built with amazing Tailwind CSS °.
+ As a researcher, I was focused on causal inference and individualized treatment effect estimation with deep learning. I also worked on explainable AI for healthcare and vision tasks.
+ Permanent residency and full work authorization in Germany. Open to relocation.
@@ -66,19 +65,15 @@
- Front-End Developer
+ Research Interests
- Since 2013
+ Causal inference, individualized treatment assignment, explainable ML
- “docs/index.html” is the main content file. By copying HTML: add pages, sections, subsection, and
- other parts.
-
-
- Important: Too much content on one page
- will break the page in the form of additional columns.
+ Built and evaluated deep learning models (MLPs, GANs, VAEs, GNNs) in TensorFlow, Keras, and PyTorch for
+ healthcare decision support, privacy, and explainability.
@@ -96,16 +91,34 @@
- WebPraktikos Inc.
+ University of Heidelberg, Germany
- Jun 2018 – Present | Web Developer
+ Apr 2020 - Oct 2025 | Ph.D. Candidate
-
- Built doner pork chop • Served salmon, cream soft cheese, and brisket • Acted 55% pork chop
- • Filled burgdoggen & frankfurter strip steak with 90% burger patties and broth
-
+
+
+ •
+ Developed individualized treatment assignment strategies using MLPs, GANs, VAEs, and GNNs in TensorFlow/Keras.
+
+
+ •
+ Designed pain patient treatment strategies using K-NN clustering and XGBoost with RCT validation.
+
+
+ •
+ Built explainable pathology patch classification with prototype learning and decision trees in PyTorch.
+
+
+ •
+ Applied digital twin models using stable diffusion for patient data privacy in PyTorch.
+
+
+ •
+ Developed a dropout prediction model for cancer patients achieving 80% precision in TensorFlow.
+
+
@@ -113,21 +126,16 @@
- Mammoth GmbH
+ National Institute of Informatics, Japan
- Feb 2017 – Apr 2018 | Android Developer
+ Oct 2018 - Apr 2019 | Research Intern
-
-
- ›
- Cooked shrimps for 2 to 3 minutes per side, or until opaque; then, transfered to a serving dish with limon
-
- ›
- Roasted a pig, turning frequently, until meat reached 160°F in the thickest part of the shoulder or thigh
+ •
+ Developed and evaluated a computer vision algorithm for long-term video prediction using PyTorch.
@@ -135,20 +143,16 @@
- Exquisite Systems d.o.o.
+ Irkutsk Branch of MSTUCA, Russia
- May 2015 – Dec 2016 | Software QA Specialist
+ Oct 2014 - Jul 2015 | Student Assistant
- ›
- Made stockfish, which is unsalted fish, usully cod, dried by cold air and wind on wooden racks on the foreshore
-
-
- ›
- Preserved meat without salt by removing fat, cutting it into very thin strips and drying it in the sun or by a fire.
+ •
+ Built a multi-camera system to capture helicopter panel data and populate digital tables automatically.
@@ -167,10 +171,10 @@
- Graz University of Technology
+ University of Heidelberg, Germany
- 2014 – 2015 | Master's Degree in Chemistry
+ 2020 - 2025 | Ph.D. in Computer Science
@@ -180,10 +184,21 @@
- Vienna University of Technology
+ Saarland University, Germany
+
+
+ 2016 - 2019 | M.Sc. in Visual Computing
+
+
+
+
+
+
+
+ Irkutsk State University, Russia
- 2010 – 2013 | Bachelor’s Degree in Biology
+ 2012 - 2016 | B.Sc. in Applied Informatics and Mathematics
@@ -191,10 +206,10 @@
- Vienna University of Technology
+ High School, Irkutsk, Russia
- Since 2019 | HTML CSS
+ WebSocket API | Docker | GitHub Actions
- Good design is as little design as possible. Less, but better — because it concentrates on the essential
- aspects, and the products are not burdened with non-essentials.
+ Developed and deployed trading bots with real-time market data ingestion, containerized workflows, and CI/CD.
- Good design is long-lasting. It avoids being fashionable and therefore never appears antiquated.
- Good design is honest. It does not make a product more innovative, powerful or valuable than it really is.
-
- Good design is innovative. Technological development is always offering new opportunities for innovative
- design.
+ Implemented persistent chat history and dynamic user memory management for a local assistant.
- Fantastic Project
+ Databricks Integration
- 2012 | JavaScript
+ Centralized storage for chats and user authentication
- Strip steak tail capicola alcatra ground round tenderloin ar. Venison tri-tip porchetta, brisket
- tenderloin pig beef.
+ Extended the assistant to store chats and auth data in a Databricks-hosted database for analytics.
@@ -292,33 +282,34 @@
- JavaScript
+ ML/AI and Data
- Middle Level
+ Research and applied machine learning
- Good parts: pure function, higher-order functions, factory functions, composition. Bad parts:
- inheritance, this, new.
+ End-to-end model development, evaluation, and explainability across healthcare and vision tasks.
- Minimal and formal résumé website template for print, mobile, and desktop. The proportions are
- the same on the screen and paper. Built with amazing Tailwind CSS °.
-
-
-
-
-
-
-
-
- Front-End Developer
-
-
- Since 2013
-
-
-
- “docs/index.html” is the main content file. By copying HTML: add pages, sections, subsection, and
- other parts.
-
-
- Important: Too much content on one page
- will break the page
- in the form of additional columns.
-
-
- If you want to change CSS in the classical way, add a class to the HTML element and write CSS inside “tailwind.css.”
-
-
-
-
-
- EXPERIENCE
+ SELECTED PUBLICATIONSd
-
-
- WebPraktikos Inc.
-
-
- Jun 2018 – Present | Web Developer
-
-
-
- Built doner pork chop • Served salmon, cream soft cheese, and brisket • Acted 55% pork chop
- • Filled burgdoggen & frankfurter strip steak with 90% burger patties and broth
-
+
+
+ A. Sirazitdinov et al., "Graph Neural Networks for Individual Treatment Effect Estimation," IEEE Access, 2024.
+
+
+ A. Sirazitdinov et al., "Review of Deep Learning Methods for Individual Treatment Effect Estimation with Automatic Hyperparameter Optimization," TechRxiv, 2022.
+
+
-
-
-
- Mammoth GmbH
-
-
- Feb 2017 – Apr 2018 | Android Developer
-
-
-
-
- ›
- Cooked shrimps for 2 to 3 minutes per side, or until opaque; then, transfered to a serving dish with limon
-
-
- ›
- Roasted a pig, turning frequently, until meat reached 160°F in the thickest part of the shoulder or thigh
-
-
-
-
-
-
-
- Exquisite Systems d.o.o.
-
-
- May 2015 – Dec 2016 | Software QA Specialist
-
-
-
-
- ›
- Made stockfish, which is unsalted fish, usully cod, dried by cold air and wind on wooden racks on the foreshore
-
-
- ›
- Preserved meat without salt by removing fat, cutting it into very thin strips and drying it in the sun or by a fire.
-
- Good design is as little design as possible. Less, but better — because it concentrates on the essential
- aspects, and the products are not burdened with non-essentials.
-
- Good design is long-lasting. It avoids being fashionable and therefore never appears antiquated.
-
-
- Good design is honest. It does not make a product more innovative, powerful or valuable than it really is.
-
-
+
+
+
+
Ask the CV Assistant
+
+
+
+
Hello! Ask me about Andrei’s experience or skills.
+
+
+
+
+
-
-
-
- Third One
-
-
- 2013 – 2014 | Vue
-
-
-
- Good design is innovative. Technological development is always offering new opportunities for innovative
- design.
-
-
- Good design emphasizes the usefulness of a product whilst disregarding anything that could possibly detract from it.
+
+ Note: the chat requires a backend service to respond.
-
-
-
-
- Fantastic Project
-
-
- 2012 | JavaScript
-
-
-
- Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.
-
-
+
-
-
-
-
+
+
-
- SKILLS
-
+
+
-
-
-
- JavaScript
-
-
- Middle Level
-
-
-
- Good parts: pure function, higher-order functions, factory functions, composition. Bad parts:
- inheritance, this, new.
-
- Minimal and formal résumé website template for print, mobile, and desktop. The proportions are
- the same on the screen and paper. Built with amazing Tailwind CSS °.
-
-
-
-
-
-
-
-
- Front-End Developer
-
-
- Since 2013
-
-
-
- “docs/index.html” is the main content file. By copying HTML: add pages, sections, subsection, and
- other parts.
-
-
- Important: Too much content on one page
- will break the page
- in the form of additional columns.
-
-
- If you want to change CSS in the classical way, add a class to the HTML element and write CSS inside “tailwind.css.”
-
-
-
-
-
-
-
-
-
-
-
- EXPERIENCE
-
-
-
-
-
- WebPraktikos Inc.
-
-
- Jun 2018 – Present | Web Developer
-
-
-
- Built doner pork chop • Served salmon, cream soft cheese, and brisket • Acted 55% pork chop
- • Filled burgdoggen & frankfurter strip steak with 90% burger patties and broth
-
-
-
-
-
-
-
-
- Mammoth GmbH
-
-
- Feb 2017 – Apr 2018 | Android Developer
-
-
-
-
- ›
- Cooked shrimps for 2 to 3 minutes per side, or until opaque; then, transfered to a serving dish with limon
-
-
- ›
- Roasted a pig, turning frequently, until meat reached 160°F in the thickest part of the shoulder or thigh
-
-
-
-
-
-
-
- Exquisite Systems d.o.o.
-
-
- May 2015 – Dec 2016 | Software QA Specialist
-
-
-
-
- ›
- Made stockfish, which is unsalted fish, usully cod, dried by cold air and wind on wooden racks on the foreshore
-
-
- ›
- Preserved meat without salt by removing fat, cutting it into very thin strips and drying it in the sun or by a fire.
-
- Good design is as little design as possible. Less, but better — because it concentrates on the essential
- aspects, and the products are not burdened with non-essentials.
-
- Good design is long-lasting. It avoids being fashionable and therefore never appears antiquated.
-
-
- Good design is honest. It does not make a product more innovative, powerful or valuable than it really is.
-
-
-
-
-
-
- Third One
-
-
- 2013 – 2014 | Vue
-
-
-
- Good design is innovative. Technological development is always offering new opportunities for innovative
- design.
-
-
- Good design emphasizes the usefulness of a product whilst disregarding anything that could possibly detract from it.
-
-
-
-
-
-
- Fantastic Project
-
-
- 2012 | JavaScript
-
-
-
- Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.
-
-
-
-
-
-
-
-
-
-
-
- SKILLS
-
-
-
-
-
- JavaScript
-
-
- Middle Level
-
-
-
- Good parts: pure function, higher-order functions, factory functions, composition. Bad parts:
- inheritance, this, new.
-