ARTS - Day1
🪐

ARTS - Day1

Created
Aug 15, 2023 01:47 PM
Tags
ARTS

Algorithm

网格图中鱼的最大数目

  • 思路
类似《图像渲染》问题,任选一点作为起点,广度/深度优先搜索出鱼数量大于0的方格,打捞后将鱼的数量记为0,防止重复计算。最终比较得出捞得鱼数最多的区块。
  • 解法
class Solution { private int[] dx = {1, 0, 0, -1}; private int[] dy = {0, 1, -1, 0}; public int findMaxFish(int[][] grid) { // ignore null check int columnCnt = grid[0].length; int rowCnt = grid.length; int max = 0; for (int i = 0; i < columnCnt; i++) { for (int j = 0; j < rowCnt; j++) { if (grid[j][i] != 0) { int cnt = findFishCountByZone(grid, i, j); max = max < cnt ? cnt : max; } } } return max; } /** * find all adjacent points's fish count and set zero */ private int findFishCountByZone(int[][] grid, int startColumn, int startRow) { int cnt = grid[startRow][startColumn]; if (cnt == 0) { return cnt; } grid[startRow][startColumn] = 0; for (int i = 0; i < 4; i++) { int row = startRow + dx[i]; int column = startColumn + dy[i]; if (row >= 0 && row < grid.length && column >= 0 && column < grid[0].length) { cnt += findFishCountByZone(grid, column, row); } } return cnt; } }

Review

Sidecar vs. Init Container in Kubernetes
https://www.baeldung.com/linux/kubernetes-sidecar-vs-init-container
平时工作中更多时间都在关注 Pod 里主容器中的业务逻辑,没有关注过 initContainer 和 sidecar Container 的作用,故找了几篇文章给自己答疑解惑。

总结二者的作用及区别

Sidecar Containers
Init Containers
作用
为主容器提供一些业务外的附加功能
为主容器的启动初始化环境
和主容器的关系
和主容器是串联关系,如下图
在主容器之前启动并退出
生命周期
和主容器一起启动,运行,终止
在主容器之前启动并退出
使用场景
日志,监控,安全
初始化环境,拉取数据供主容器启动使用
notion image

sidecar 容器使用示例

来自 Kubernetes sidecar container overview,介绍了一个处理日志的 sidecar 容器设计,定义 nginx 的日志目录为 volume,从而读取主容器的日志内容进行处理。
metadata: name: simple-webapp labels: app: webapp spec: containers: - name: main-application image: nginx volumeMounts: - name: shared-logs mountPath: /var/log/nginx - name: sidecar-container image: busybox command: ["sh","-c","while true; do cat /var/log/nginx/access.log; sleep 30; done"] volumeMounts: - name: shared-logs mountPath: /var/log/nginx volumes: - name: shared-logs emptyDir: {} --- # Service Configuration # -------------------- apiVersion: v1 kind: Service metadata: name: simple-webapp labels: run: simple-webapp spec: ports: - port: 80 protocol: TCP selector: app: webapp type: NodePort

Technique/Tips

使用 Streamlit 搭建一个简单的小网页

突然想到用 OpenAI 的 API 做些轻量的小应用玩玩,对比了一下发现使用 Streamlit 非常简单。

Streamlit demo

pip install streamlit streamlit hello

搭建步骤

前置准备
  • Zeabur 账号:非常方便的一键式服务部署平台
  1. 编写页面
这一步可以直接让 ChatGPT 代写,写一个初版然后不断让 ChatGPT 优化。
# -*- coding: utf-8 -*- import openai import os import logging import functools import requests import streamlit as st from streamlit_lottie import st_lottie logger = logging.getLogger("streamlit-openai") logger.setLevel(logging.INFO) openai.api_key = os.getenv("OPENAI_API_KEY") max_tokens = os.getenv("OPENAI_MAX_TOKENS") max_tokens = int(max_tokens) if max_tokens else 1024 def handle_exception(default=None): def wrapper(fn): @functools.wraps(fn) def wrapped(*args, **kwargs): try: return fn(*args, **kwargs) except Exception as e: logger.exception(e) return default or str(e) return wrapped return wrapper def load_lottie_url(url): r = requests.get(url) if r.status_code != 200: return None return r.json() # chatbot @handle_exception() def chat_fn(prompt: str) -> str: if not prompt: return "" engine = os.getenv("CHAT_ENGINE") or "text-davinci-003" res = openai.Completion.create( engine=engine, prompt=prompt, max_tokens=max_tokens ) return res["choices"][0]["text"] # image generation @handle_exception() def img_gen_fn(prompt: str) -> str: if not prompt: return "" res = openai.Image.create( prompt=prompt, n=1, size="1024x1024" ) return res["data"][0]["url"] # text summary @handle_exception() def summary_fn(prompt: str) -> str: if not prompt: return "" engine = os.getenv("CHAT_ENGINE") or "text-davinci-002" res = openai.Completion.create( engine=engine, prompt=f"Summarize this:\n\n{prompt}", max_tokens=max_tokens ) return res["choices"][0]["text"] # title and description st.set_page_config( page_title="ChatBot", page_icon="🤖", layout="wide" ) st.title("Little Bot") lottie_chat = load_lottie_url('https://assets5.lottiefiles.com/packages/lf20_fcfjwiyb.json') st_lottie(lottie_chat, speed=1, height=150, key="initial") st.info(""" + 🤖 **在左侧选择要使用的工具** 1. 对话 2. 图像生成 3. 文字总结 + @see https://github.com/kaftsang/varierity-of-docs """) st.sidebar.header('导航') page = st.sidebar.radio("选择一个页面", ["聊天", "图像生成", "总结文字"]) user_input = st.text_input("随便说些什么吧") logger.info("request prompt: %s" % user_input) if page == "聊天": if st.button("发送"): response = chat_fn(user_input) logger.info("response: %s" % user_input) st.success('成功!', icon="✅") st.write(response) if page == "图像生成": if st.button("生成"): response = img_gen_fn(user_input) logger.info("response: %s" % user_input) st.success('成功!', icon="✅") st.image(response) if page == "总结文字": if st.button("发送"): response = summary_fn(user_input) logger.info("response: %s" % user_input) st.success('成功!', icon="✅") st.write(response) st.sidebar.markdown('---') st.sidebar.markdown('Made with OpenAI API by [Kevin Tsang](https://zengkangfu.com/)')
  1. 准备部署容器环境
FROM python:3 WORKDIR /app CMD pip install streamlit \ && pip install openai \ && pip install streamlit_lottie \ && streamlit run https://raw.githubusercontent.com/kaftsang/varierity-of-docs/main/streamlit/streamlit.py ENV PORT=8501 HOST=0.0.0.0 EXPOSE 8501
8501 是 Streamlit 的默认启动端口,将这个文件放在 Git 仓库的根目录。
  1. 应用部署
在 Zeabur 导入 Git 仓库,配置环境变量 OPENAI_API_KEY 为 OpenAI 的 API Token,到这里就全部完成了。
notion image

Share