- Removed Python translator entry from CLAUDE.md documentation - Deleted JavaScript code editor shortcut keys implementation file - Removed PHP configuration file with font settings - Deleted Python to PHP converter script (conv.php) - Removed web conversion endpoint (web/public/convert.php) - Deleted font selection component (web/include/font.php) - Removed main index page with iframe layout (web/public/index.php) - Deleted input page with Python editor (web/public/input.php) - Removed language selection dropdown (web/include/lang.php) - Deleted mixed Python-PHP test cases file - Removed output page with PHP display (web/public/output.php) - Deleted APIpull/15/head
parent
633a7d232c
commit
719b2ce4fc
55 changed files with 0 additions and 13047 deletions
@ -1,12 +0,0 @@ |
||||
from modelscope.pipelines import pipeline |
||||
from modelscope.outputs import OutputKeys |
||||
from PIL import Image |
||||
from background_generation import modelscope_warpper |
||||
|
||||
model = "damo/cv_background_generation_sd" |
||||
pipe = pipeline('background_generation_task', model=model, device='gpu',auto_collate=False,model_revision='v1.1.0') |
||||
main_image='https://vision-poster.oss-cn-shanghai.aliyuncs.com/lllcho.lc/data/test_data/demo_example/%E5%8C%96%E5%A6%86%E5%93%81/1c33fc5e8b084269ffdb4e0557c2c3c4.png' |
||||
reference_image='https://vision-poster.oss-cn-shanghai.aliyuncs.com/lllcho.lc/data/test_data/5d873b5f64b82bcbb235748347602dce38c6ec1d.jpg' |
||||
out=pipe(main_image,reference_image,num_images_per_prompt=1) |
||||
imgs=out[OutputKeys.OUTPUT_IMGS] |
||||
imgs[0].save(f'result.jpg') |
||||
@ -1,15 +0,0 @@ |
||||
from modelscope.pipelines import pipeline |
||||
from modelscope.outputs import OutputKeys |
||||
from PIL import Image |
||||
from background_generation import modelscope_warpper |
||||
|
||||
model = "damo/cv_background_generation_sd" |
||||
pipe = pipeline('background_generation_task', model=model, device='gpu', auto_collate=False, model_revision='v1.1.0') |
||||
out = pipe( |
||||
'https://vision-poster.oss-cn-shanghai.aliyuncs.com/lllcho.lc/data/test_data/demo_example/%E5%8C%96%E5%A6%86%E5%93%81/1c33fc5e8b084269ffdb4e0557c2c3c4.png', |
||||
'https://vision-poster.oss-cn-shanghai.aliyuncs.com/lllcho.lc/data/test_data/5d873b5f64b82bcbb235748347602dce38c6ec1d.jpg', |
||||
num_inference_steps=20, |
||||
num_images_per_prompt=2, |
||||
seed=None, |
||||
noise_level=500 |
||||
) |
||||
@ -1,55 +0,0 @@ |
||||
import cv2 |
||||
import os |
||||
import numpy as np |
||||
import torch |
||||
from modelscope import snapshot_download |
||||
from PIL import Image |
||||
import onnxruntime |
||||
|
||||
def softmax(x): |
||||
x -= np.max(x, axis=0, keepdims=True) |
||||
x = np.exp(x) / np.sum(np.exp(x), axis=0, keepdims=True) |
||||
return x |
||||
|
||||
def get_rot(image, ort_session): |
||||
img_cv = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR) |
||||
img_clone = img_cv.copy() |
||||
img_np = cv2.resize(img_cv, (224, 224)) |
||||
img_np = img_np.astype(np.float32) |
||||
mean = np.array([103.53, 116.28, 123.675], dtype=np.float32).reshape((1, 1, 3)) |
||||
norm = np.array([0.01742919, 0.017507, 0.01712475], dtype=np.float32).reshape((1, 1, 3)) |
||||
img_np = (img_np - mean) * norm |
||||
img_tensor = torch.from_numpy(img_np) |
||||
img_tensor = img_tensor.unsqueeze(0) |
||||
img_nchw = img_tensor.permute(0, 3, 1, 2) |
||||
ort_inputs = {ort_session.get_inputs()[0].name: img_nchw.numpy()} |
||||
outputs = ort_session.run(None, ort_inputs) |
||||
logits = outputs[0].reshape((-1,)) |
||||
probs = softmax(logits) |
||||
rot_idx = np.argmax(probs) |
||||
if rot_idx == 1: |
||||
print('rot 90') |
||||
img_clone = cv2.transpose(img_clone) |
||||
img_clone = np.flip(img_clone, 1) |
||||
return Image.fromarray(cv2.cvtColor(img_clone, cv2.COLOR_BGR2RGB)) |
||||
elif rot_idx == 2: |
||||
print('rot 180') |
||||
img_clone = cv2.flip(img_clone, -1) |
||||
return Image.fromarray(cv2.cvtColor(img_clone, cv2.COLOR_BGR2RGB)) |
||||
elif rot_idx == 3: |
||||
print('rot 270') |
||||
img_clone = cv2.transpose(img_clone) |
||||
img_clone = np.flip(img_clone, 0) |
||||
return Image.fromarray(cv2.cvtColor(img_clone, cv2.COLOR_BGR2RGB)) |
||||
else: |
||||
return image |
||||
|
||||
model_dir = snapshot_download('Cherrytest/rot_bgr', revision='v1.0.0') |
||||
model_path = os.path.join(model_dir, 'rot_bgr.onnx') |
||||
ort_session = onnxruntime.InferenceSession(model_path) |
||||
img_path = 'path_of_your_image' |
||||
image = Image.open(img_path) |
||||
image = image.convert('RGB') |
||||
image = get_rot(image, ort_session) |
||||
out_path = 'path_to_save_image' |
||||
image.save(out_path) |
||||
@ -1,52 +0,0 @@ |
||||
import tempfile |
||||
from modelscope.msdatasets import MsDataset |
||||
from modelscope.metainfo import Trainers |
||||
from modelscope.trainers import build_trainer |
||||
from modelscope.utils.constant import DownloadMode |
||||
from modelscope.utils.hub import snapshot_download |
||||
|
||||
|
||||
train_dataset = MsDataset( |
||||
MsDataset.load( |
||||
"coco_2014_caption", |
||||
namespace="modelscope", |
||||
split="train[:100]", |
||||
download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS).remap_columns({ |
||||
'image': 'image', |
||||
'caption': 'text' |
||||
})) |
||||
test_dataset = MsDataset( |
||||
MsDataset.load( |
||||
"coco_2014_caption", |
||||
namespace="modelscope", |
||||
split="validation[:20]", |
||||
download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS).remap_columns({ |
||||
'image': 'image', |
||||
'caption': 'text' |
||||
})) |
||||
|
||||
|
||||
def cfg_modify_fn(cfg): |
||||
cfg.train.hooks = [{ |
||||
'type': 'CheckpointHook', |
||||
'interval': 2 |
||||
}, { |
||||
'type': 'TextLoggerHook', |
||||
'interval': 1 |
||||
}, { |
||||
'type': 'IterTimerHook' |
||||
}] |
||||
cfg.train.max_epochs=2 |
||||
return cfg |
||||
|
||||
pretrained_model = 'damo/ofa_pretrain_base_zh' |
||||
pretrain_path = snapshot_download(pretrained_model, revision='v1.0.2') |
||||
|
||||
args = dict( |
||||
model=pretrain_path, |
||||
train_dataset=train_dataset, |
||||
eval_dataset=test_dataset, |
||||
cfg_modify_fn=cfg_modify_fn, |
||||
work_dir = tempfile.TemporaryDirectory().name) |
||||
trainer = build_trainer(name=Trainers.ofa, default_args=args) |
||||
trainer.train() |
||||
@ -1,28 +0,0 @@ |
||||
# require modelscope>=0.3.7,目前默认已经超过,您检查一下即可 |
||||
# 按照更新镜像的方法处理或者下面的方法 |
||||
# pip install --upgrade modelscope -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html |
||||
# 需要单独安装decord,安装方法:pip install decord |
||||
import torch |
||||
from modelscope.utils.constant import Tasks |
||||
from modelscope.pipelines import pipeline |
||||
from modelscope.preprocessors.image import load_image |
||||
|
||||
pipeline = pipeline(task=Tasks.multi_modal_embedding, |
||||
model='damo/multi-modal_clip-vit-large-patch14_336_zh', model_revision='v1.0.1') |
||||
input_img = load_image('https://clip-cn-beijing.oss-cn-beijing.aliyuncs.com/pokemon.jpeg') # 支持皮卡丘示例图片路径/本地图片 返回PIL.Image |
||||
input_texts = ["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"] |
||||
|
||||
# 支持一张图片(PIL.Image)或多张图片(List[PIL.Image])输入,输出归一化特征向量 |
||||
img_embedding = pipeline.forward({'img': input_img})['img_embedding'] # 2D Tensor, [图片数, 特征维度] |
||||
|
||||
# 支持一条文本(str)或多条文本(List[str])输入,输出归一化特征向量 |
||||
text_embedding = pipeline.forward({'text': input_texts})['text_embedding'] # 2D Tensor, [文本数, 特征维度] |
||||
|
||||
# 计算图文相似度 |
||||
with torch.no_grad(): |
||||
# 计算内积得到logit,考虑模型temperature |
||||
logits_per_image = (img_embedding / pipeline.model.temperature) @ text_embedding.t() |
||||
# 根据logit计算概率分布 |
||||
probs = logits_per_image.softmax(dim=-1).cpu().numpy() |
||||
|
||||
print("图文匹配概率:", probs) |
||||
@ -1,10 +0,0 @@ |
||||
add = "http://c.biancheng.net/python/,http://c.biancheng.net/shell/" |
||||
# 一个简单的for循环 |
||||
for i in add: |
||||
if i == ',': |
||||
# 忽略本次循环的剩下语句 |
||||
print('\n') |
||||
continue |
||||
elif i == '.': |
||||
break |
||||
print(i, end="") |
||||
@ -1,13 +0,0 @@ |
||||
import time |
||||
import driver |
||||
import json |
||||
|
||||
file_username = 'js' |
||||
current_time = time.time() # 获取当前时间 |
||||
one_day = 86400 # 定义时间间隔为一天(86400秒) |
||||
# 检查是否需要重新获取cookies |
||||
if 'last_cookie_time' not in driver.__dict__ or current_time - driver.last_cookie_time >= one_day: |
||||
pass |
||||
|
||||
if 'last_cookie_time' not in driver.__dict__ and current_time - driver.last_cookie_time >= one_day: |
||||
pass |
||||
@ -1,17 +0,0 @@ |
||||
def gen_fib(count): |
||||
i = 1 |
||||
if count == 0: |
||||
fib = [] |
||||
elif count == 1: |
||||
fib = [1] |
||||
elif count == 2: |
||||
fib = [1,1] |
||||
elif count > 2: |
||||
fib = [1,1] |
||||
while i < (count - 1): |
||||
fib.append(fib[i] + fib[i-1]) |
||||
i += 1 |
||||
|
||||
return fib |
||||
|
||||
print(gen_fib(10)) |
||||
@ -1,3 +0,0 @@ |
||||
price_val = 6.12658 |
||||
world = "swoole" |
||||
print(f'{price_val:.2f}, hello={world}') # 6.13 |
||||
@ -1,5 +0,0 @@ |
||||
from datetime import datetime; |
||||
|
||||
date_val = datetime.utcnow() |
||||
|
||||
print(f'{date_val=:%Y-%m-%d}') # date_val=2021-07-09 |
||||
@ -1,822 +0,0 @@ |
||||
#!/usr/bin/python |
||||
# -*- coding: UTF-8 -*- |
||||
from selenium import webdriver |
||||
from selenium.webdriver.edge.options import Options |
||||
from selenium.webdriver.common.by import By |
||||
from selenium.common.exceptions import NoSuchElementException,InvalidArgumentException |
||||
from selenium.webdriver import ActionChains |
||||
from selenium.webdriver.common.actions.action_builder import ActionBuilder |
||||
import json,base64,time,random,hashlib,math,operator,sys,os,sqlite3,_thread,atexit |
||||
from PIL import Image |
||||
from functools import reduce |
||||
|
||||
# 程序初始化 |
||||
global randarr,game,driver,file_username,sqlite3_cur,isCreateImage,isCityWar,isLog,runUsername |
||||
isLog = False |
||||
isCityWar = False |
||||
isCreateImage = False |
||||
isGarrisonQueueRand = True |
||||
randarr = {} |
||||
|
||||
# ----------------程序功能函数库--------------- |
||||
def mkdirs(dirs): |
||||
if not os.path.exists(dirs): |
||||
os.makedirs(dirs) |
||||
|
||||
def ocr(path): |
||||
pass |
||||
# ocr = PaddleOCR(enable_mkldnn=True,use_angle_cls=False,use_gpu=False, lang="ch") |
||||
# result = ocr.ocr(path, cls=False) |
||||
# return result |
||||
def connetctDb(): |
||||
global sqlite3_cur |
||||
sqlite3_conn = sqlite3.connect('data/ttapp.db') |
||||
print ("sqlite3数据库连接成功") |
||||
sqlite3_cur = sqlite3_conn.cursor() |
||||
def initDb(): |
||||
global sqlite3_cur,isLog |
||||
if isLog: |
||||
connetctDb() |
||||
try: |
||||
create_tb_cmd=''' |
||||
CREATE TABLE IF NOT EXISTS game_resource_grain_data_log |
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT, |
||||
uid TEXT NOT NULL, |
||||
estimated_quantity INTEGER NOT NULL, |
||||
quantity INTEGER NOT NULL, |
||||
create_time INTEGER NOT NULL |
||||
); |
||||
''' |
||||
sqlite3_cur.execute(create_tb_cmd) |
||||
create_tb_cmd=''' |
||||
CREATE TABLE IF NOT EXISTS game_resource_timber_data_log |
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT, |
||||
uid TEXT NOT NULL, |
||||
estimated_quantity INTEGER NOT NULL, |
||||
quantity INTEGER NOT NULL, |
||||
create_time INTEGER NOT NULL |
||||
); |
||||
''' |
||||
sqlite3_cur.execute(create_tb_cmd) |
||||
create_tb_cmd=''' |
||||
CREATE TABLE IF NOT EXISTS game_resource_stone_data_log |
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT, |
||||
uid TEXT NOT NULL, |
||||
estimated_quantity INTEGER NOT NULL, |
||||
quantity INTEGER NOT NULL, |
||||
create_time INTEGER NOT NULL |
||||
); |
||||
''' |
||||
sqlite3_cur.execute(create_tb_cmd) |
||||
create_tb_cmd=''' |
||||
CREATE TABLE IF NOT EXISTS game_resource_iron_data_log |
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT, |
||||
uid TEXT NOT NULL, |
||||
estimated_quantity INTEGER NOT NULL, |
||||
quantity INTEGER NOT NULL, |
||||
create_time INTEGER NOT NULL |
||||
); |
||||
''' |
||||
#主要就是上面的语句 |
||||
sqlite3_cur.execute(create_tb_cmd) |
||||
except Exception as err: |
||||
print("Create table failed") |
||||
print(err) |
||||
return False |
||||
def init(): |
||||
global driver,runUsername |
||||
mkdirs('data') |
||||
mkdirs('runtime/temp') |
||||
initDb() |
||||
options = Options() |
||||
# prefs = {'download.default_directory' : '/dev/null', |
||||
# 'download.prompt_for_download': False, |
||||
# 'download.directory_upgrade': True, |
||||
# 'safebrowsing.enabled': True} |
||||
# options.add_experimental_option('prefs', prefs) |
||||
options.add_experimental_option("excludeSwitches",["enable-automation"]) |
||||
options.add_experimental_option("useAutomationExtension",False) |
||||
options.add_argument("--allow-reporter-logs=false") |
||||
options.add_argument('--disable-dev-shm-usage') |
||||
options.add_argument('--disable-blink-features=AutomationControlled') |
||||
if sys.platform == 'linux': |
||||
# options.add_argument("--disable-gpu") |
||||
# options.add_argument('--no-sandbox') |
||||
# options.add_argument('--user-data-dir=./'+file_username) |
||||
pass |
||||
driver = webdriver.Edge(options=options) |
||||
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { |
||||
"source": """ |
||||
Object.defineProperty(navigator, 'webdriver', { |
||||
get: () => undefined |
||||
}) |
||||
""" |
||||
}) |
||||
# driver.set_window_size(700, 950) |
||||
driver.set_window_size(700, 950) |
||||
driver.implicitly_wait(30) |
||||
driver.get("https://www.huya.com/myfollow") |
||||
with open(file_username+'.cookies.json', 'r') as cookies_file: |
||||
cookies_data = json.load(cookies_file) |
||||
for cookie in cookies_data: |
||||
driver.add_cookie(cookie) |
||||
|
||||
# runUsername = driver.get_cookie('username')['value'] |
||||
runUsername = '' |
||||
|
||||
# 流程第一步刷新页面 |
||||
def refresh(time = 15,initOneLoad = False): |
||||
driver.get('https://www.huya.com/16695719') |
||||
if initOneLoad: |
||||
driver.find_element(By.ID,'player-gift-word').click() |
||||
find_element_game() |
||||
wait(time,'程序加载中。。。') |
||||
|
||||
# 找到Canvas |
||||
def find_element_game(): |
||||
driver.find_element(By.CSS_SELECTOR,'.more-activity-icon').click() |
||||
driver.find_element(By.ID,'front-0cenz7bj_web_video_com').click() |
||||
app = driver.find_element(By.CSS_SELECTOR,'.videoComp-90808de0[style="width: 566px; height: 788px; top: 50%; left: 50%;"]') |
||||
driver.switch_to.frame(app.find_element(By.CSS_SELECTOR,'iframe')) |
||||
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR,'body > iframe')) |
||||
global game |
||||
game = driver.find_element(By.ID,'GameCanvas') |
||||
|
||||
# 等待游戏加载 |
||||
def wait(n,msg=''): |
||||
for i in range(0,n): |
||||
time.sleep(1) |
||||
print (msg+str(i+1)+'s') |
||||
|
||||
# take_element_screenshot |
||||
def take_element_screenshot(path=''): |
||||
name = '' |
||||
if path != '': |
||||
name = str(random.randint(11,999999999)) |
||||
runtimename = 'runtime'+os.sep+path+'Screenshot'+name+'.'+file_username+'.png'; |
||||
screenshotjs = ''' |
||||
let callback = arguments[arguments.length - 1]; |
||||
cc.director.on(cc.Director.EVENT_AFTER_DRAW, () => { |
||||
// 获取画布元素 |
||||
let gameCanvas = document.getElementById("GameCanvas") |
||||
// 图片转换为(base64)dataURL |
||||
let imagebase64 = gameCanvas.toDataURL() |
||||
// 取消渲染注册 |
||||
cc.director.off(cc.Director.EVENT_AFTER_DRAW) |
||||
callback(imagebase64) |
||||
}) |
||||
''' |
||||
screenshot = driver.execute_async_script(screenshotjs) |
||||
screenshot = screenshot.replace('data:image/png;base64,','') |
||||
screenshot = base64.urlsafe_b64decode(screenshot) |
||||
with open(runtimename, "wb") as screenshot_file: |
||||
screenshot_file.write(screenshot) |
||||
return runtimename |
||||
def load_config(): |
||||
with open(file_username+'.config.json', 'r') as config_file: |
||||
config = json.load(config_file) |
||||
return config |
||||
def random_game_type(config): |
||||
global randarr |
||||
sha256 = hashlib.sha256() |
||||
sha256.update(str(config).encode('utf-8')) |
||||
key = sha256.hexdigest() |
||||
print(key) |
||||
max = 0 |
||||
if not key in randarr: |
||||
randarr.update({key:[]}) |
||||
print(config.values()) |
||||
for temp in config.values(): |
||||
max += float(temp) |
||||
for k,v in config.items(): |
||||
v = float(v)/max*10000 |
||||
|
||||
for val in range(0,int(v)): |
||||
# print(k) |
||||
randarr[key].append(k) |
||||
|
||||
return randarr[key][random.randint(0,len(randarr[key]))] |
||||
def actions_game_click(x,y,time = 1): |
||||
global driver,game |
||||
w = 283 |
||||
h = 394 |
||||
if x == w: |
||||
x = 0 |
||||
else: |
||||
x = x-w |
||||
if y == h: |
||||
y = 0 |
||||
else: |
||||
y = y-h |
||||
|
||||
# action = ActionBuilder(driver) |
||||
# action.pointer_action.move_to_location(x,y)\ |
||||
# .click() |
||||
# action.perform() |
||||
ActionChains(driver)\ |
||||
.move_to_element_with_offset(game, x, y)\ |
||||
.click()\ |
||||
.perform() |
||||
wait(time,'操作等待。。') |
||||
def page_drag(x,y,x1,y1): |
||||
# 鼠标拖动页面 |
||||
action_builder = ActionBuilder(driver) |
||||
action_builder.pointer_action.move_to_location(x,y).click_and_hold() |
||||
action_builder.pointer_action.move_to_location(x1,y1) |
||||
action_builder.key_action.pause() |
||||
action_builder.pointer_action.release() |
||||
action_builder.key_action.pause() |
||||
action_builder.perform() |
||||
def image_compare(image1,image2): |
||||
''' |
||||
:param pic1: 图片1路径 |
||||
:param pic2: 图片2路径 |
||||
:return: 返回对比的结果 |
||||
''' |
||||
histogram1 = image1.histogram() |
||||
histogram2 = image2.histogram() |
||||
|
||||
differ = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2,histogram1, histogram2)))/len(histogram1)) |
||||
print('图片相识度',differ) |
||||
return differ < 15.0 |
||||
|
||||
def image_crop(path,w,h,x1,y1): |
||||
''' |
||||
:param path: 图片1路径 |
||||
:param w: 宽度 |
||||
:param h: 高度 |
||||
:param x1: x坐标 |
||||
:param y1: y坐标 |
||||
:return: 返回对比的结果 |
||||
''' |
||||
im = Image.open(path) |
||||
#crop(x1,y1,x2,y2) 裁剪的是矩形 左上(x1,y1) 到右下(x2,y2) |
||||
cropim = im.crop((x1, y1, x1+w, y1+h)) |
||||
# cropim.save("cropim.png") |
||||
global isCreateImage |
||||
if isCreateImage: |
||||
cropim.save(path) |
||||
return cropim |
||||
|
||||
def check_equal(runtimename,name,w,h,x1,y1): |
||||
cropim = image_crop(runtimename,w,h,x1,y1) |
||||
name = 'static'+ os.sep + name |
||||
im = Image.open(name) |
||||
return image_compare(im,cropim) |
||||
def ocr_list(cropim): |
||||
runtimename = 'runtime/ScreenshotCropOcr.'+file_username+'.png' |
||||
cropim.save(runtimename) |
||||
result = ocr(runtimename) |
||||
temp = [] |
||||
for line in result: |
||||
temp.append(line[1][0]) |
||||
return temp |
||||
def check_equal_ocr(runtimename,w,h,x1,y1): |
||||
cropim = image_crop(runtimename,w,h,x1,y1) |
||||
return ocr_list(cropim) |
||||
|
||||
# --------------------------业务动作函数库-------------------------- |
||||
yyy = 45 # 不同的显示偏移 |
||||
def home_resource_points(): |
||||
actions_game_click(35,597+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_ok(): |
||||
actions_game_click(267-67,543+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_my(): |
||||
actions_game_click(106-67,189+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_snatch(): |
||||
actions_game_click(117-67,264+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_farmland_garrison(t=3): |
||||
actions_game_click(500-67,146+25+yyy,t) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_logging_yard_garrison(t=3): |
||||
actions_game_click(500-67,193+25+yyy,t) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_quarry_garrison(t=3): |
||||
actions_game_click(500-67,245+25+yyy,t) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_iron_ore_stationed(t=3): |
||||
actions_game_click(500-67,291+25+yyy,t) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def go_resource_points(): |
||||
actions_game_click(100-67,95+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_details_close(): |
||||
actions_game_click(555-67,35+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_details_garrison(): |
||||
actions_game_click(345-67,571+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
|
||||
def resource_points_details_obtain_ok(): |
||||
actions_game_click(345-67,525+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
def resource_points_next_page(): |
||||
# 资源列表下一页 |
||||
page_drag(343-67,564+25+yyy,343-67,564+25+yyy-260) |
||||
def resource_points_pre_page(): |
||||
# 资源列表上一页 |
||||
page_drag(343-67,330+25+yyy,343-67,330+25+yyy+260) |
||||
def resource_points_ok2(): |
||||
actions_game_click(488-67,543+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
def resource_points_ok3(): |
||||
# 起始位为默认位置 否则使用resource_points_ok |
||||
resource_points_next_page() |
||||
actions_game_click(267-67,543+25+yyy) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
# 首页王城入口 |
||||
def city_home(): |
||||
actions_game_click(43,188,3) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
# 关闭王城说明 |
||||
def city_close_say(): |
||||
actions_game_click(531,158,3) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
# 展开王城资源列表 |
||||
def city_open_resource_list(): |
||||
actions_game_click(516,277) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
# 一键收取王城资源 |
||||
def city_one_key_resource_list(): |
||||
actions_game_click(416,649) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
def city_go_home(): |
||||
actions_game_click(31,31) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
# --------------------------业务函数库----------------------------- |
||||
def ok_over(): |
||||
resource_points_snatch() |
||||
resource_points_my() |
||||
|
||||
def check_garrison(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'noGarrisonCompare.png',360, 32,103,304) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_garrison_idle_barracks(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'noIdleBarracksCompare.png',50,25,420,180) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
|
||||
def check_garrison_has_idle_barracks(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'IdleBarracksCompare.png',50,25,420,180) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_garrison_has_or_no_idle_barracks(): |
||||
runtimename = take_element_screenshot() |
||||
result = False |
||||
if check_equal(runtimename,'noIdleBarracksCompare.png',50,25,420,180): |
||||
result = 1 |
||||
elif check_equal(runtimename,'IdleBarracksCompare.png',50,25,420,180): |
||||
result = 2 |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_not_stationed(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'ResourcePointsAreNotStationedAtThisTimeCompare.png',115, 65,110,410) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
|
||||
def check_resource_points_cancel(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'CancelGarrisonCompare.png',73, 20,198,599) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_ok(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'okGarrisonCompare.png',60, 20,157,599) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_ok2(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'okGarrisonCompare2.png',73, 20,198,599) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_has_ok(): |
||||
runtimename = take_element_screenshot() |
||||
if check_equal(runtimename,'okGarrisonCompare.png',60, 20,157,599): |
||||
result = 1 |
||||
elif check_equal(runtimename,'okGarrisonCompare2.png',73, 20,198,599): |
||||
result = 2 |
||||
elif check_equal(runtimename,'CancelGarrisonCompare.png',73, 20,198,599): |
||||
result = 3 |
||||
else: |
||||
result = False |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_details_cancel(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'CancelGarrisonCompare2.png',70, 28,196,624) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
def check_resource_points_page(): |
||||
runtimename = take_element_screenshot() |
||||
result = check_equal(runtimename,'resourcePointsPage.png',238,60,20,205) |
||||
# os.remove(runtimename) |
||||
print('当前函数:',sys._getframe().f_code.co_name) |
||||
return result |
||||
|
||||
def over_garrison_xy(xy=0): |
||||
if xy == 0: |
||||
resource_points_ok() |
||||
elif xy==1: |
||||
resource_points_ok2() |
||||
elif xy==2: |
||||
resource_points_ok3() |
||||
else: |
||||
pass |
||||
# 取消驻守 |
||||
def over_garrison(n = 1,xy= 0): |
||||
i = 0 |
||||
while i < n: |
||||
print('取消驻守循环:',i,'-',n) |
||||
if not check_resource_points_page(): |
||||
refresh() |
||||
home_resource_points() |
||||
if check_resource_points_not_stationed(): |
||||
# 是否有资源驻守 |
||||
print('未有驻守的资源点1') |
||||
return False |
||||
result = check_resource_points_has_ok() |
||||
print('xxxxxxx',result,'xxxxxxx') |
||||
if result == 1: |
||||
over_garrison_xy(xy) |
||||
if check_resource_points_ok(): |
||||
continue |
||||
elif result == 2: |
||||
over_garrison_xy(xy) |
||||
if check_resource_points_ok2(): |
||||
continue |
||||
elif result == 3: |
||||
over_garrison_xy(xy) |
||||
resource_points_details_garrison() |
||||
if check_resource_points_details_cancel(): |
||||
resource_points_details_close() |
||||
continue |
||||
else: |
||||
if check_resource_points_not_stationed(): |
||||
print('未有驻守的资源点2') |
||||
return False |
||||
if check_resource_points_details_cancel(): |
||||
resource_points_details_close() |
||||
continue |
||||
resource_points_details_obtain_ok() |
||||
i += 1 |
||||
# 驻守 |
||||
def run_garrison(n = 1,types = ''): |
||||
i = 0 |
||||
step = 0 |
||||
sleep = 3 |
||||
if isGarrisonQueueRand == False: |
||||
type = random_game_type(types) |
||||
print('本轮驻守类型'+type) |
||||
while i < n: |
||||
if isGarrisonQueueRand: |
||||
type = random_game_type(types) |
||||
print('本轮该兵营驻守类型'+type) |
||||
type = int(type) |
||||
if type == 1: |
||||
resource_points_farmland_garrison(sleep) |
||||
elif type == 2: |
||||
resource_points_logging_yard_garrison(sleep) |
||||
elif type == 3: |
||||
resource_points_quarry_garrison(sleep) |
||||
elif type == 4: |
||||
resource_points_iron_ore_stationed(sleep) |
||||
else: |
||||
print('资源类型判断失败') |
||||
if check_resource_points_page(): |
||||
print('------0----信息更新-----') |
||||
continue |
||||
|
||||
if not check_garrison(): |
||||
# 有人占了 没有到资源点详情 |
||||
print('------1----check_garrison-----') |
||||
step = step + 1 |
||||
# 临时处理 页面空白情况 等待延迟到6秒 |
||||
sleep = sleep * 2 |
||||
if sleep > 6: |
||||
sleep = 6 |
||||
if step > 10: |
||||
take_element_screenshot('temp'+os.sep) |
||||
refresh() |
||||
home_resource_points() |
||||
step = 0 |
||||
continue |
||||
resource_points_details_close() |
||||
go_resource_points() |
||||
continue |
||||
resource_points_details_garrison() |
||||
if check_garrison(): |
||||
# true 表示 卡住了 有人占了 |
||||
print('------2----check_garrison-----') |
||||
resource_points_details_close() |
||||
go_resource_points() |
||||
continue |
||||
resource_points_details_garrison() |
||||
res = check_garrison_has_or_no_idle_barracks() |
||||
if res == 1: |
||||
# 驻守中 |
||||
resource_points_details_close() |
||||
elif res == 2: |
||||
# 空闲 有人驻守了 跳出循环重新选资源 |
||||
resource_points_details_close() |
||||
go_resource_points() |
||||
continue |
||||
else: |
||||
pass |
||||
go_resource_points() |
||||
if check_resource_points_page(): |
||||
print('-------go home----------') |
||||
else: |
||||
print('-------go home fail reload go home ----------') |
||||
go_resource_points() |
||||
|
||||
sleep = 3 |
||||
i = i+1 |
||||
|
||||
#一键 王城 |
||||
def resource_one_key_king_over(): |
||||
# 关掉资源页 |
||||
resource_points_details_close() |
||||
# 进入王城争夺 |
||||
city_home() |
||||
# 关闭说明 |
||||
city_close_say() |
||||
# 展开占领资源 |
||||
city_open_resource_list() |
||||
# 一键领取 |
||||
city_one_key_resource_list() |
||||
resource_points_details_obtain_ok() |
||||
city_go_home() |
||||
home_resource_points() |
||||
pass |
||||
|
||||
def resource_points_xy_screenshot_ocr(filename,xy=0): |
||||
if xy == 0: |
||||
cropim = image_crop(filename,180,230,100,400) |
||||
else: |
||||
cropim = image_crop(filename,337,30,120,140) |
||||
return ocr_list(cropim) |
||||
def check_resource_points_over(n=1,t=1,times=0): |
||||
i = 0 |
||||
temp = n |
||||
# 更新游戏截图 |
||||
filename = take_element_screenshot() |
||||
while i < n: |
||||
if i < 2: |
||||
result = resource_points_xy_screenshot_ocr(filename,i) |
||||
if '收取' in result: |
||||
over_garrison(n=1,xy=i) |
||||
filename = take_element_screenshot() |
||||
n-=1 |
||||
else: |
||||
i+=1 |
||||
else: |
||||
resource_points_next_page() |
||||
filename = take_element_screenshot() |
||||
result = resource_points_xy_screenshot_ocr(filename,0) |
||||
if '收取' in result: |
||||
over_garrison(n=1,xy=0) |
||||
n-=1 |
||||
else: |
||||
i+=1 |
||||
ok_over() |
||||
# 根据 n 剩余等待时间 开始补充驻守 |
||||
if temp-n > 0 and times > 60*3: |
||||
run_garrison(temp-n,t) |
||||
|
||||
def check_over_resource_points_thread(msg,n=1,type=1,times= 0): |
||||
print('OCR截图检测线程',n,type,msg) |
||||
check_resource_points_over(n,type,times) |
||||
print('OCR截图检测线程结束') |
||||
|
||||
# -----------------------主程序--------------------------- |
||||
def run_image(name='run'): |
||||
global file_username,isCityWar,driver,game,isCreateImage |
||||
file_username = name |
||||
isCreateImage = True |
||||
init() |
||||
refresh(5) |
||||
home_resource_points() |
||||
ok_over() |
||||
# ---------------------------- |
||||
# check_resource_points_page() |
||||
# check_resource_points_not_stationed() |
||||
# check_resource_points_ok() |
||||
# check_resource_points_ok2() |
||||
# ---------------------------- |
||||
resource_points_farmland_garrison() |
||||
# ----------------------------- |
||||
check_garrison() |
||||
# ----------------------------- |
||||
# resource_points_details_garrison() |
||||
# ---------------------------- |
||||
# check_garrison_has_idle_barracks() |
||||
# check_garrison_idle_barracks() |
||||
# ---------------------------- |
||||
# resource_points_details_close() |
||||
# go_resource_points() |
||||
# ---------------------------- |
||||
# check_resource_points_cancel() |
||||
# ---------------------------- |
||||
# resource_points_ok() |
||||
# ------------------------ |
||||
# check_resource_points_details_cancel() |
||||
# ------------------------ |
||||
# resource_points_details_garrison() |
||||
# resource_points_details_obtain_ok() |
||||
pass |
||||
|
||||
def run(numberOfBarracks = 1,type = '',times = 600): |
||||
global isCityWar,isLog,file_username |
||||
if not check_resource_points_page(): |
||||
refresh() |
||||
home_resource_points() |
||||
ok_over() |
||||
over_garrison(numberOfBarracks) |
||||
run_garrison(numberOfBarracks,type) |
||||
if isLog: |
||||
over_nums_log() |
||||
if isCityWar: |
||||
resource_one_key_king_over() |
||||
|
||||
# 休眠开始写入时间 |
||||
timeFileName = file_username + '.runtime' |
||||
startSleepTime = int(round(time.time() * 1000)) |
||||
endSleepTime = startSleepTime + (times*1000) |
||||
timeFile = str(startSleepTime) + ',' + str(endSleepTime) |
||||
with open(timeFileName, "wb") as timeFile_file: |
||||
timeFile_file.write(timeFile.encode('utf-8')) |
||||
# 更新 cookies |
||||
current_time = time.time() # 获取当前时间 |
||||
one_day = 86400 # 定义时间间隔为一天(86400秒) |
||||
# 检查是否需要重新获取cookies |
||||
if 'last_cookie_time' not in driver.__dict__ or current_time - driver.last_cookie_time >= one_day: |
||||
# 更新cookies |
||||
cookies = driver.get_cookies() |
||||
if cookies: |
||||
cookies = json.dumps(cookies) |
||||
with open(file_username + '.cookies.json', 'wb') as cookies_file: |
||||
cookies_file.write(cookies.encode('utf-8')) |
||||
|
||||
# 更新最后获取cookie的时间 |
||||
driver.last_cookie_time = current_time |
||||
# 休眠 |
||||
for i in range(0,times): |
||||
# 取10 并且不等于0 |
||||
# if i > 0 and not i%60: |
||||
# 截图进行检测 |
||||
# print('开启线程截图检测') |
||||
# _thread.start_new_thread(check_over_resource_points_thread,('thread-check_over_resource_points-1',numberOfBarracks,type,i,)) |
||||
time.sleep(1) |
||||
print (file_username+'程序休眠中。。。'+str(i+1)+'s') |
||||
# 休眠结束写入时间 |
||||
timeFile = ''; |
||||
with open(timeFileName, "wb") as timeFile_file: |
||||
timeFile_file.write(timeFile.encode('utf-8')) |
||||
def over_nums_log(): |
||||
global runUsername |
||||
sqlite3_conn = sqlite3.connect('data/ttapp.db') |
||||
print ("sqlite3数据库连接成功") |
||||
sqlite3_cur = sqlite3_conn.cursor() |
||||
runtimename = take_element_screenshot() |
||||
cropim = image_crop(runtimename,566,88,0,700) |
||||
runtimename = 'runtime/ScreenshotCropOcr.'+file_username+'.png' |
||||
cropim.save(runtimename) |
||||
reslut = ocr(runtimename) |
||||
# print (reslut) |
||||
temp = [] |
||||
for line in reslut: |
||||
if not line[1][0] == '+' and not line[1][0] == '旅': |
||||
temp.append(line[1][0]) |
||||
print (temp) |
||||
t = time.time() |
||||
t = int(t) |
||||
try: |
||||
sql='''INSERT INTO game_resource_grain_data_log (uid,estimated_quantity,quantity,create_time) VALUES ('%s',0,%s,%s);''' |
||||
sql = sql % (runUsername,temp[0],t) |
||||
print(sql) |
||||
sqlite3_cur.execute(sql) |
||||
sql='''INSERT INTO game_resource_timber_data_log (uid,estimated_quantity,quantity,create_time) VALUES ('%s',0,%s,%s);''' |
||||
sql = sql % (runUsername,temp[1],t) |
||||
print(sql) |
||||
sqlite3_cur.execute(sql) |
||||
sql='''INSERT INTO game_resource_stone_data_log (`uid`,`estimated_quantity`,`quantity`,`create_time`) VALUES ('%s',0,%s,%s);''' |
||||
sql = sql % (runUsername,temp[2],t) |
||||
print(sql) |
||||
sqlite3_cur.execute(sql) |
||||
sql = '''INSERT INTO game_resource_iron_data_log (`uid`,`estimated_quantity`,`quantity`,`create_time`) VALUES ('%s',0,%s,%s);''' |
||||
sql = sql % (runUsername,temp[3],t) |
||||
print(sql) |
||||
sqlite3_cur.execute(sql) |
||||
sqlite3_conn.commit() |
||||
except Exception as e: |
||||
print('资源数据记录',e) |
||||
def run_game_shell(name = 'run'): |
||||
global file_username,isCityWar |
||||
file_username = name |
||||
init() |
||||
initOneLoad = True |
||||
if sys.platform == 'linux': |
||||
initOneLoad = False |
||||
refresh(15,initOneLoad) |
||||
home_resource_points() |
||||
while True: |
||||
# 每次循环 重新加载配置 |
||||
config = load_config() |
||||
# |
||||
isCityWar = config['cityWar']['isOpen'] |
||||
type = config['arr'] |
||||
if 'isGarrisonQueueRand' in config: |
||||
isGarrisonQueueRand = config['isGarrisonQueueRand'] |
||||
try: |
||||
run(config['numberOfBarracks'],type,config['time']) |
||||
except Exception as err: |
||||
print(err) |
||||
refresh() |
||||
wait(30) |
||||
home_resource_points() |
||||
continue; |
||||
def login(name='run'): |
||||
options = Options() |
||||
global driver |
||||
driver = webdriver.Edge(options=options) |
||||
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { |
||||
"source": """ |
||||
Object.defineProperty(navigator, 'webdriver', { |
||||
get: () => undefined |
||||
}) |
||||
""" |
||||
}) |
||||
driver.implicitly_wait(10) |
||||
driver.get('https://www.huya.com/myfollow') |
||||
wait(100,'请在倒计时结束前完成登录。。。') |
||||
cookies = driver.get_cookies() |
||||
if not cookies == []: |
||||
cookies = json.dumps(cookies) |
||||
with open(name+'.cookies.json', 'wb') as cookies_file: |
||||
cookies_file.write(cookies.encode('utf-8')) |
||||
configPath = name+'.config.json' |
||||
if not os.path.exists(configPath): |
||||
configtext = '''{"arr":{"1":"0.1","2":"0.1","3":"0.1","4":"0.1"},"numberOfBarracks":3,"time":840,"cityWar":{"isOpen":false}}''' |
||||
with open(configPath, 'wb') as cookies_file: |
||||
cookies_file.write(configtext.encode('utf-8')) |
||||
|
||||
driver.quit() |
||||
|
||||
@atexit.register |
||||
def cleanExit(): |
||||
timeFile = sys.argv[1:][0] + '.runtime' |
||||
if os.path.exists(timeFile): |
||||
os.unlink(timeFile) |
||||
|
||||
def main(argv): |
||||
print(argv) |
||||
if not argv == [] and argv[0] == 'login': |
||||
print('login ...') |
||||
if len(argv) > 1: |
||||
login(argv[1]) |
||||
else: |
||||
login() |
||||
print('login over') |
||||
elif not argv == [] and argv[0] == 'image': |
||||
run_image(argv[1]) |
||||
pass |
||||
else: |
||||
print('rungame ...') |
||||
if len(argv) == 1: |
||||
run_game_shell(argv[0]) |
||||
elif len(argv) == 2: |
||||
global isCreateImage |
||||
isCreateImage = True |
||||
run_game_shell(argv[0]) |
||||
else: |
||||
print('not give argv') |
||||
main(sys.argv[1:]) |
||||
@ -1 +0,0 @@ |
||||
|
||||
@ -1,33 +0,0 @@ |
||||
from pycparser import CParser, parse_file, c_ast |
||||
|
||||
# 解析 C 代码并打印函数声明及定义 |
||||
def extract_functions_from_file(filename): |
||||
# 解析 C 文件 |
||||
ast = parse_file(filename, use_cpp=True) |
||||
|
||||
# 用于存储函数声明和实现 |
||||
function_declarations = [] |
||||
function_definitions = [] |
||||
|
||||
# 遍历 AST |
||||
for node in ast.ext: |
||||
# 检查节点类型 |
||||
if isinstance(node, c_ast.FuncDef): |
||||
# 如果是函数定义,保存定义 |
||||
function_definitions.append(node.decl.name) |
||||
elif isinstance(node, c_ast.Decl): |
||||
# 如果是函数声明 |
||||
if isinstance(node.type, c_ast.FuncType): |
||||
function_declarations.append(node.name) |
||||
|
||||
# 输出结果 |
||||
print("Function Declarations:") |
||||
for decl in function_declarations: |
||||
print(decl) |
||||
|
||||
print("\nFunction Definitions:") |
||||
for defi in function_definitions: |
||||
print(defi) |
||||
|
||||
# 调用函数,解析指定文件 |
||||
extract_functions_from_file('your_file.c') # 替换为你的 C 源文件 |
||||
@ -1,304 +0,0 @@ |
||||
<?php |
||||
$operator = PyCore::import("operator"); |
||||
$builtins = PyCore::import("builtins"); |
||||
/** 与之对应的是多行注释 |
||||
用三个双引号表示,这两段双引号当中的内容都会被视作是注释 |
||||
*/ |
||||
|
||||
$values = new PyList([]); |
||||
$kv = new PyDict([ |
||||
"hello" => "world", |
||||
]); |
||||
$__value = 3; |
||||
$values->__setitem__(0, $__value); |
||||
$__value = 10; |
||||
$values->__setitem__(1, $__value); |
||||
$c = 1 + 1; |
||||
$d = 8 - 1; |
||||
$e = 10 * 2; |
||||
$f = 35 / 5; |
||||
$g = $operator->floordiv(5 , 3); |
||||
$h = $operator->floordiv(-5 , 3); |
||||
$j = $operator->floordiv(5.5 , 3); |
||||
$k = $operator->floordiv(-5 , 3); |
||||
$__value = 7 % 3; |
||||
$values->__setitem__(10, $__value); |
||||
$__value = $operator->pow(2 , 3); |
||||
$values->__setitem__(11, $__value); |
||||
$__value = 1 + 3 * 2; |
||||
$values->__setitem__(12, $__value); |
||||
$__value = 1 + 3 * 2; |
||||
$values->__setitem__(13, $__value); |
||||
$_ = true; |
||||
$_ = false; |
||||
$_ = !true; |
||||
$_ = !false; |
||||
$_ = true && false; |
||||
$_ = false || true; |
||||
$_ = true + true; |
||||
$_ = true * 8; |
||||
$_ = false - 5; |
||||
$_ = 0 == false; |
||||
$_ = 1 == true; |
||||
$_ = 2 == true; |
||||
$_ = -5 != false; |
||||
$_ = PyCore::bool(0); |
||||
$_ = PyCore::bool(4); |
||||
$_ = PyCore::bool(-6); |
||||
$_ = 0 && 2; |
||||
$_ = -5 || 0; |
||||
$_ = 1 == 1; |
||||
$_ = 2 == 1; |
||||
$_ = 1 != 1; |
||||
$_ = 2 != 1; |
||||
$_ = 1 < 10; |
||||
$_ = 1 > 10; |
||||
$_ = 2 <= 2; |
||||
$_ = 2 >= 2; |
||||
$_ = 1 < 2 && 2 < 3; |
||||
$_ = 2 < 3 && 3 < 2; |
||||
$_ = 1 < 2; |
||||
$_ = 2 < 3; |
||||
$a = new PyList([1, 2, 3, 4]); |
||||
$b = $a; |
||||
$_ = $b == $a; |
||||
$_ = $b == $a; |
||||
$_ = new PyList([1, 2, 3, 4]); |
||||
$_ = $b == $a; |
||||
$_ = $b == $a; |
||||
$_ = "This is a string."; |
||||
$_ = "This is also a string."; |
||||
$_ = "Hello " + "world!"; |
||||
$_ = "Hello world!"; |
||||
$_ = "This is a string"->__getitem__(0); |
||||
$_ = PyCore::len("This is a string"); |
||||
$name = "Reiko"; |
||||
$_ = "She said her name is " . $name . "."; |
||||
$_ = $name . " is " . PyCore::len($name) . " characters long."; |
||||
$_ = null; |
||||
$_ = "etc" == null; |
||||
$_ = null == null; |
||||
$_ = PyCore::bool(null); |
||||
$_ = PyCore::bool(0); |
||||
$_ = PyCore::bool(""); |
||||
$_ = PyCore::bool(new PyList([])); |
||||
$_ = PyCore::bool(new PyDict([ |
||||
])); |
||||
$_ = PyCore::bool([]); |
||||
PyCore::print("I'm Python. Nice to meet you!"); |
||||
PyCore::print("Hello, World", end: "!"); |
||||
$input_string_var = PyCore::input("Enter some data: "); |
||||
$some_var = 5; |
||||
$_ = 3 > 2 ? "yahoo!" : 2; |
||||
|
||||
function test() { |
||||
if (3 > 2) { |
||||
return "yahoo"; |
||||
} else { |
||||
return 2; |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
$li = new PyList([]); |
||||
$other_li = new PyList([4, 5, 6]); |
||||
$li->append(1); |
||||
$li->append(2); |
||||
$li->append(4); |
||||
$li->append(3); |
||||
$li->pop(); |
||||
$li->append(3); |
||||
$_ = $li->__getitem__(0); |
||||
$_ = $li->__getitem__(-1); |
||||
$_ = $li->__getitem__(4); |
||||
$_ = $li->__getitem__(PyCore::slice(1, 3, null)); |
||||
$_ = $li->__getitem__(PyCore::slice(2, null, null)); |
||||
$_ = $li->__getitem__(PyCore::slice(null, 3, null)); |
||||
$_ = $li->__getitem__(PyCore::slice(null, null, 2)); |
||||
$_ = $li->__getitem__(PyCore::slice(null, null, -1)); |
||||
$li2 = $li->__getitem__(PyCore::slice(null, null, null)); |
||||
$li->__delitem__(2); |
||||
|
||||
$li->remove(2); |
||||
$li->remove(2); |
||||
$li->insert(1, 2); |
||||
$li->index(2); |
||||
$li->index(4); |
||||
$tup = [1, 2, 3]; |
||||
$tup->__getitem__(0); |
||||
$__value = 3; |
||||
$tup->__setitem__(0, $__value); |
||||
PyCore::type(1); |
||||
PyCore::type([1]); |
||||
PyCore::type([]); |
||||
$_ = PyCore::len($tup); |
||||
$_ = $tup + [4, 5, 6]; |
||||
$_ = $tup->__getitem__(PyCore::slice(null, 2, null)); |
||||
$_ = $tup->__contains__(2); |
||||
[$a, $b, $c] = [1, 2, 3]; |
||||
[$d, $e, $f] = [4, 5, 6]; |
||||
[$e, $d] = [$d, $e]; |
||||
$invalid_dict = new PyDict([ |
||||
1 => "123", |
||||
]); |
||||
$_ = $invalid_dict->__getitem__("one"); |
||||
$_ = $invalid_dict->get("one"); |
||||
$filled_dict = new PyDict([ |
||||
"one" => 1, |
||||
"two" => 2, |
||||
"three" => 3, |
||||
]); |
||||
$_ = PyCore::list($filled_dict->keys()); |
||||
$_ = PyCore::list($filled_dict->keys()); |
||||
$_ = PyCore::list($filled_dict->values()); |
||||
$_ = PyCore::list($filled_dict->values()); |
||||
$_ = $filled_dict->__contains__("one"); |
||||
$_ = $filled_dict->__contains__(1); |
||||
$empty_set = PyCore::set(); |
||||
$some_set = new PySet([1, 1, 2, 2, 3, 4]); |
||||
$other_set = new PySet([3, 4, 5, 6]); |
||||
$filled_set = new PySet([1, 2, 3]); |
||||
$_ = $operator->bitand($filled_set , $other_set); |
||||
$_ = $operator->bitor($filled_set , $other_set); |
||||
$_ = new PySet([1, 2, 3, 4]) - new PySet([2, 3, 5]); |
||||
$_ = $operator->bitxor(new PySet([1, 2, 3, 4]) , new PySet([2, 3, 5])); |
||||
$_ = new PySet([1, 2]) >= new PySet([1, 2, 3]); |
||||
$_ = new PySet([1, 2]) <= new PySet([1, 2, 3]); |
||||
if ($some_var > 10) { |
||||
PyCore::print("some_var is totally bigger than 10."); |
||||
} else { |
||||
if ($some_var < 10) { |
||||
PyCore::print("some_var is smaller than 10."); |
||||
} else { |
||||
PyCore::print("some_var is indeed 10."); |
||||
} |
||||
|
||||
} |
||||
|
||||
$__iter = PyCore::iter(new PyList(["dog", "cat", "mouse"])); |
||||
while($current = PyCore::next($__iter)) { |
||||
$animal = $current; |
||||
PyCore::print(PyCore::str("{} is a mammal")->format($animal)); |
||||
} |
||||
$__iter = PyCore::iter(PyCore::range(4)); |
||||
while($current = PyCore::next($__iter)) { |
||||
$i = $current; |
||||
PyCore::print($i); |
||||
} |
||||
$animals = new PyList(["dog", "cat", "mouse"]); |
||||
$__iter = PyCore::iter(PyCore::enumerate($animals)); |
||||
while($current = PyCore::next($__iter)) { |
||||
[$i, $value] = $current; |
||||
PyCore::print($i, $value); |
||||
} |
||||
$x = 0; |
||||
while($x < 4) { |
||||
PyCore::print($x); |
||||
$x += 1; |
||||
} |
||||
try { |
||||
throw $builtins->IndexError("This is an index error"); |
||||
} catch(PyError $e) { |
||||
if (PyCore::isinstance($e, $builtins->IndexError)) { |
||||
throw $builtins->IndexError("This is an index error"); |
||||
} elseif (PyCore::isinstance($e, new PyTuple([$builtins->TypeError, $builtins->NameError]))) { |
||||
throw $builtins->IndexError("This is an index error"); |
||||
} else { |
||||
throw $e; |
||||
} |
||||
} finally { |
||||
PyCore::print("We can clean up resources here"); |
||||
} |
||||
$f__object = PyCore::open("myfile.txt"); |
||||
$f = $f__object->__enter__(); |
||||
try { |
||||
$__iter = PyCore::iter($f); |
||||
while($current = PyCore::next($__iter)) { |
||||
$line = $current; |
||||
PyCore::print($line); |
||||
} |
||||
} finally { |
||||
$f__object->__exit__(); |
||||
} |
||||
|
||||
$contents = new PyDict([ |
||||
"aa" => 12, |
||||
"bb" => 21, |
||||
]); |
||||
$file__object = PyCore::open("myfile1.txt", "w+"); |
||||
$file = $file__object->__enter__(); |
||||
try { |
||||
$file->write(PyCore::str($contents)); |
||||
} finally { |
||||
$file__object->__exit__(); |
||||
} |
||||
|
||||
$file__object = PyCore::open("myfile2.txt", "w+"); |
||||
$file = $file__object->__enter__(); |
||||
try { |
||||
$file->write($json->dumps($contents)); |
||||
} finally { |
||||
$file__object->__exit__(); |
||||
} |
||||
|
||||
$file__object = PyCore::open("myfile1.txt", "r+"); |
||||
$file = $file__object->__enter__(); |
||||
try { |
||||
$contents = $file->read(); |
||||
} finally { |
||||
$file__object->__exit__(); |
||||
} |
||||
|
||||
PyCore::print($contents); |
||||
$file__object = PyCore::open("myfile2.txt", "r+"); |
||||
$file = $file__object->__enter__(); |
||||
try { |
||||
$contents = $json->load($file); |
||||
} finally { |
||||
$file__object->__exit__(); |
||||
} |
||||
|
||||
PyCore::print($contents); |
||||
$filled_dict = new PyDict([ |
||||
"one" => 1, |
||||
"two" => 2, |
||||
"three" => 3, |
||||
]); |
||||
$our_iterable = $filled_dict->keys(); |
||||
PyCore::print($our_iterable); |
||||
$__iter = PyCore::iter($our_iterable); |
||||
while($current = PyCore::next($__iter)) { |
||||
$i = $current; |
||||
PyCore::print($i); |
||||
} |
||||
$our_iterable->__getitem__(1); |
||||
$our_iterator = PyCore::iter($our_iterable); |
||||
PyCore::next($our_iterator); |
||||
PyCore::next($our_iterator); |
||||
PyCore::next($our_iterator); |
||||
PyCore::next($our_iterator); |
||||
$our_iterator = PyCore::iter($our_iterable); |
||||
$__iter = PyCore::iter($our_iterator); |
||||
while($current = PyCore::next($__iter)) { |
||||
$i = $current; |
||||
PyCore::print($i); |
||||
} |
||||
PyCore::list($our_iterable); |
||||
PyCore::list($our_iterator); |
||||
|
||||
function add($x, $y) { |
||||
PyCore::print(PyCore::str("x is {} and y is {}")->format($x, $y)); |
||||
return $x + $y; |
||||
} |
||||
|
||||
|
||||
add(5, 6); |
||||
add(y: 6, x: 5); |
||||
|
||||
function varargs(...$args) { |
||||
return $args; |
||||
} |
||||
|
||||
|
||||
varargs(1, 2, 3); |
||||
@ -1,407 +0,0 @@ |
||||
# Python中单行注释用#表示,#之后同行字符全部认为被注释 |
||||
|
||||
""" 与之对应的是多行注释 |
||||
用三个双引号表示,这两段双引号当中的内容都会被视作是注释 |
||||
""" |
||||
|
||||
values = [] |
||||
kv = {'hello': 'world'} |
||||
|
||||
# 获得一个整数 |
||||
values[0] = 3 |
||||
# 获得一个浮点数 |
||||
values[1] = 10.0 |
||||
|
||||
c = 1 + 1 # => 2 |
||||
d = 8 - 1 # => 7 |
||||
e = 10 * 2 # => 20 |
||||
f = 35 / 5 # => 7.0 |
||||
|
||||
g = 5 // 3 # => 1 |
||||
h = -5 // 3 # => -2 |
||||
j = 5.5 // 3.0 # => 1.0 # works on floats too |
||||
k = -5.0 // 3.0 # => -2.0 |
||||
|
||||
# Modulo operation |
||||
values[10] = 7 % 3 # => 1 |
||||
|
||||
# Exponentiation (x**y, x to the yth power) |
||||
values[11] = 2 ** 3 # => 8 |
||||
|
||||
# Enforce precedence with parentheses |
||||
values[12] = 1 + 3 * 2 # => 7 |
||||
values[13] = (1 + 3) * 2 # => 8 |
||||
|
||||
_ = True # => True |
||||
_ = False # => False |
||||
|
||||
_ = not True # => False |
||||
_ = not False # => True |
||||
|
||||
# Boolean Operators |
||||
# Note "and" and "or" are case-sensitive |
||||
_ = True and False # => False |
||||
_ = False or True # => True |
||||
|
||||
_ = True + True # => 2 |
||||
_ = True * 8 # => 8 |
||||
_ = False - 5 # => -5 |
||||
|
||||
_ = 0 == False # => True |
||||
_ = 1 == True # => True |
||||
_ = 2 == True # => False |
||||
_ = -5 != False # => True |
||||
|
||||
_ = bool(0) # => False |
||||
_ = bool(4) # => True |
||||
_ = bool(-6) # => True |
||||
_ = 0 and 2 # => 0 |
||||
_ = -5 or 0 # => -5 |
||||
|
||||
# Equality is == |
||||
_ = 1 == 1 # => True |
||||
_ = 2 == 1 # => False |
||||
|
||||
# Inequality is != |
||||
_ = 1 != 1 # => False |
||||
_ = 2 != 1 # => True |
||||
|
||||
# More comparisons |
||||
_ = 1 < 10 # => True |
||||
_ = 1 > 10 # => False |
||||
_ = 2 <= 2 # => True |
||||
_ = 2 >= 2 # => True |
||||
|
||||
# Seeing whether a value is in a range |
||||
_ = 1 < 2 and 2 < 3 # => True |
||||
_ = 2 < 3 and 3 < 2 # => False |
||||
# Chaining makes this look nicer |
||||
_ = 1 < 2 < 3 # => True |
||||
_ = 2 < 3 < 2 # => False |
||||
|
||||
a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4] |
||||
b = a # Point b at what a is pointing to |
||||
_ = b is a # => True, a and b refer to the same object |
||||
_ = b == a # => True, a's and b's objects are equal |
||||
_ = b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4] |
||||
_ = b is a # => False, a and b do not refer to the same object |
||||
_ = b == a # => True, a's and b's objects are equal |
||||
|
||||
# Strings are created with " or ' |
||||
_ = "This is a string." |
||||
_ = 'This is also a string.' |
||||
|
||||
# Strings can be added too! But try not to do this. |
||||
_ = "Hello " + "world!" # => "Hello world!" |
||||
# String literals (but not variables) can be concatenated without using '+' |
||||
_ = "Hello " "world!" # => "Hello world!" |
||||
|
||||
# A string can be treated like a list of characters |
||||
_ = "This is a string"[0] # => 'T' |
||||
|
||||
# You can find the length of a string |
||||
_ = len("This is a string") # => 16 |
||||
|
||||
# You can also format using f-strings or formatted string literals (in Python 3.6+) |
||||
name = "Reiko" |
||||
_ = f"She said her name is {name}." # => "She said her name is Reiko" |
||||
# You can basically put any Python statement inside the braces and it will be output in the string. |
||||
_ = f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long." |
||||
|
||||
# None is an object |
||||
_ = None # => None |
||||
|
||||
# Don't use the equality "==" symbol to compare objects to None |
||||
# Use "is" instead. This checks for equality of object identity. |
||||
_ = "etc" is None # => False |
||||
_ = None is None # => True |
||||
|
||||
# None, 0, and empty strings/lists/dicts/tuples all evaluate to False. |
||||
# All other values are True |
||||
_ = bool(None) # => False |
||||
_ = bool(0) # => False |
||||
_ = bool("") # => False |
||||
_ = bool([]) # => False |
||||
_ = bool({}) # => False |
||||
_ = bool(()) # => False |
||||
|
||||
# Python has a print function |
||||
print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you! |
||||
|
||||
# By default the print function also prints out a newline at the end. |
||||
# Use the optional argument end to change the end string. |
||||
print("Hello, World", end="!") # => Hello, World! |
||||
|
||||
# Simple way to get input data from console |
||||
input_string_var = input("Enter some data: ") # Returns the data as a string |
||||
# Note: In earlier versions of Python, input() method was named as raw_input() |
||||
|
||||
# There are no declarations, only assignments. |
||||
# Convention is to use lower_case_with_underscores |
||||
some_var = 5 |
||||
|
||||
# Accessing a previously unassigned variable is an exception. |
||||
# See Control Flow to learn more about exception handling. |
||||
|
||||
# if can be used as an expression |
||||
# Equivalent of C's '?:' ternary operator |
||||
_ = "yahoo!" if 3 > 2 else 2 # => "yahoo!" |
||||
|
||||
|
||||
def test(): |
||||
if 3 > 2: |
||||
return 'yahoo' |
||||
else: |
||||
return 2 |
||||
|
||||
|
||||
# Lists store sequences |
||||
li = [] |
||||
# You can start with a prefilled list |
||||
other_li = [4, 5, 6] |
||||
|
||||
# Add stuff to the end of a list with append |
||||
li.append(1) # li is now [1] |
||||
li.append(2) # li is now [1, 2] |
||||
li.append(4) # li is now [1, 2, 4] |
||||
li.append(3) # li is now [1, 2, 4, 3] |
||||
# Remove from the end with pop |
||||
li.pop() # => 3 and li is now [1, 2, 4] |
||||
# Let's put it back |
||||
li.append(3) # li is now [1, 2, 4, 3] again. |
||||
|
||||
# Access a list like you would any array |
||||
_ = li[0] # => 1 |
||||
# Look at the last element |
||||
_ = li[-1] # => 3 |
||||
|
||||
# Looking out of bounds is an IndexError |
||||
_ = li[4] # Raises an IndexError |
||||
|
||||
# You can look at ranges with slice syntax. |
||||
# The start index is included, the end index is not |
||||
# (It's a closed/open range for you mathy types.) |
||||
_ = li[1:3] # Return list from index 1 to 3 => [2, 4] |
||||
_ = li[2:] # Return list starting from index 2 => [4, 3] |
||||
_ = li[:3] # Return list from beginning until index 3 => [1, 2, 4] |
||||
_ = li[::2] # Return list selecting every second entry => [1, 4] |
||||
_ = li[::-1] # Return list in reverse order => [3, 4, 2, 1] |
||||
# Use any combination of these to make advanced slices |
||||
# li[start:end:step] |
||||
|
||||
# Make a one layer deep copy using slices |
||||
li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false. |
||||
|
||||
# Remove arbitrary elements from a list with "del" |
||||
del li[2] # li is now [1, 2, 3] |
||||
|
||||
# Remove first occurrence of a value |
||||
li.remove(2) # li is now [1, 3] |
||||
li.remove(2) # Raises a ValueError as 2 is not in the list |
||||
|
||||
# Insert an element at a specific index |
||||
li.insert(1, 2) # li is now [1, 2, 3] again |
||||
|
||||
# Get the index of the first item found matching the argument |
||||
li.index(2) # => 1 |
||||
li.index(4) # Raises a ValueError as 4 is not in the list |
||||
|
||||
# Tuples are like lists but are immutable. |
||||
tup = (1, 2, 3) |
||||
tup[0] # => 1 |
||||
tup[0] = 3 # Raises a TypeError |
||||
|
||||
type((1)) # => <class 'int'> |
||||
type((1,)) # => <class 'tuple'> |
||||
type(()) # => <class 'tuple'> |
||||
|
||||
_ = len(tup) # => 3 |
||||
_ = tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) |
||||
_ = tup[:2] # => (1, 2) |
||||
_ = 2 in tup # => True |
||||
|
||||
# You can unpack tuples (or lists) into variables |
||||
a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 |
||||
# You can also do extended unpacking |
||||
# Tuples are created by default if you leave out the parentheses |
||||
d, e, f = 4, 5, 6 # tuple 4, 5, 6 is unpacked into variables d, e and f |
||||
# respectively such that d = 4, e = 5 and f = 6 |
||||
# Now look how easy it is to swap two values |
||||
e, d = d, e # d is now 5 and e is now 4 |
||||
|
||||
# Look up values with [] |
||||
invalid_dict = {1: "123"} |
||||
_ = invalid_dict["one"] # => 1 |
||||
_ = invalid_dict.get('one') # => 1 |
||||
|
||||
# Here is a prefilled dictionary |
||||
filled_dict = {"one": 1, "two": 2, "three": 3} |
||||
|
||||
# Get all keys as an iterable with "keys()". We need to wrap the call in list() |
||||
# to turn it into a list. We'll talk about those later. Note - for Python |
||||
# versions <3.7, dictionary key ordering is not guaranteed. Your results might |
||||
# not match the example below exactly. However, as of Python 3.7, dictionary |
||||
# items maintain the order at which they are inserted into the dictionary. |
||||
_ = list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7 |
||||
_ = list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+ |
||||
|
||||
# Get all values as an iterable with "values()". Once again we need to wrap it |
||||
# in list() to get it out of the iterable. Note - Same as above regarding key |
||||
# ordering. |
||||
_ = list(filled_dict.values()) # => [3, 2, 1] in Python <3.7 |
||||
_ = list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+ |
||||
|
||||
# Check for existence of keys in a dictionary with "in" |
||||
_ = "one" in filled_dict # => True |
||||
_ = 1 in filled_dict # => False |
||||
|
||||
# _ = {'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} |
||||
# _ = {'a': 1, **{'a': 2}} # => {'a': 2} |
||||
|
||||
# Sets store ... well sets |
||||
empty_set = set() |
||||
# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry. |
||||
some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4} |
||||
|
||||
# Do set intersection with & |
||||
# 计算交集 |
||||
other_set = {3, 4, 5, 6} |
||||
filled_set = {1, 2, 3} |
||||
_ = filled_set & other_set # => {3, 4, 5} |
||||
|
||||
# Do set union with | |
||||
# 计算并集 |
||||
_ = filled_set | other_set # => {1, 2, 3, 4, 5, 6} |
||||
|
||||
# Do set difference with - |
||||
# 计算差集 |
||||
_ = {1, 2, 3, 4} - {2, 3, 5} # => {1, 4} |
||||
|
||||
# Do set symmetric difference with ^ |
||||
# 这个有点特殊,计算对称集,也就是去掉重复元素剩下的内容 |
||||
_ = {1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} |
||||
|
||||
# Check if set on the left is a superset of set on the right |
||||
_ = {1, 2} >= {1, 2, 3} # => False |
||||
|
||||
# Check if set on the left is a subset of set on the right |
||||
_ = {1, 2} <= {1, 2, 3} # => True |
||||
|
||||
if some_var > 10: |
||||
print("some_var is totally bigger than 10.") |
||||
elif some_var < 10: # This elif clause is optional. |
||||
print("some_var is smaller than 10.") |
||||
else: # This is optional too. |
||||
print("some_var is indeed 10.") |
||||
|
||||
for animal in ["dog", "cat", "mouse"]: |
||||
# You can use format() to interpolate formatted strings |
||||
print("{} is a mammal".format(animal)) |
||||
|
||||
for i in range(4): |
||||
print(i) |
||||
|
||||
animals = ["dog", "cat", "mouse"] |
||||
for i, value in enumerate(animals): |
||||
print(i, value) |
||||
|
||||
x = 0 |
||||
while x < 4: |
||||
print(x) |
||||
x += 1 # Shorthand for x = x + 1 |
||||
|
||||
# Handle exceptions with a try/except block |
||||
try: |
||||
# Use "raise" to raise an error |
||||
raise IndexError("This is an index error") |
||||
except IndexError as e: |
||||
pass # Pass is just a no-op. Usually you would do recovery here. |
||||
except (TypeError, NameError): |
||||
pass # Multiple exceptions can be handled together, if required. |
||||
finally: # Execute under all circumstances |
||||
print("We can clean up resources here") |
||||
|
||||
|
||||
# Instead of try/finally to cleanup resources you can use a with statement |
||||
# 代替使用try/finally语句来关闭资源 |
||||
with open("myfile.txt") as f: |
||||
for line in f: |
||||
print(line) |
||||
|
||||
# Writing to a file |
||||
# 使用with写入文件 |
||||
contents = {"aa": 12, "bb": 21} |
||||
with open("myfile1.txt", "w+") as file: |
||||
file.write(str(contents)) # writes a string to a file |
||||
|
||||
with open("myfile2.txt", "w+") as file: |
||||
file.write(json.dumps(contents)) # writes an object to a file |
||||
|
||||
# Reading from a file |
||||
# 使用with读取文件 |
||||
with open('myfile1.txt', "r+") as file: |
||||
contents = file.read() # reads a string from a file |
||||
print(contents) |
||||
# print: {"aa": 12, "bb": 21} |
||||
|
||||
with open('myfile2.txt', "r+") as file: |
||||
contents = json.load(file) # reads a json object from a file |
||||
print(contents) |
||||
# print: {"aa": 12, "bb": 21} |
||||
|
||||
# Python offers a fundamental abstraction called the Iterable. |
||||
# An iterable is an object that can be treated as a sequence. |
||||
# The object returned by the range function, is an iterable. |
||||
|
||||
filled_dict = {"one": 1, "two": 2, "three": 3} |
||||
our_iterable = filled_dict.keys() |
||||
print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface. |
||||
|
||||
# We can loop over it. |
||||
for i in our_iterable: |
||||
print(i) # Prints one, two, three |
||||
|
||||
# However we cannot address elements by index. |
||||
our_iterable[1] # Raises a TypeError |
||||
|
||||
# An iterable is an object that knows how to create an iterator. |
||||
our_iterator = iter(our_iterable) |
||||
|
||||
# Our iterator is an object that can remember the state as we traverse through it. |
||||
# We get the next object with "next()". |
||||
next(our_iterator) # => "one" |
||||
|
||||
# It maintains state as we iterate. |
||||
next(our_iterator) # => "two" |
||||
next(our_iterator) # => "three" |
||||
|
||||
# After the iterator has returned all of its data, it raises a StopIteration exception |
||||
next(our_iterator) # Raises StopIteration |
||||
|
||||
# We can also loop over it, in fact, "for" does this implicitly! |
||||
our_iterator = iter(our_iterable) |
||||
for i in our_iterator: |
||||
print(i) # Prints one, two, three |
||||
|
||||
# You can grab all the elements of an iterable or iterator by calling list() on it. |
||||
list(our_iterable) # => Returns ["one", "two", "three"] |
||||
list(our_iterator) # => Returns [] because state is saved |
||||
|
||||
# Use "def" to create new functions |
||||
def add(x, y): |
||||
print("x is {} and y is {}".format(x, y)) |
||||
return x + y # Return values with a return statement |
||||
|
||||
# Calling functions with parameters |
||||
add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 |
||||
|
||||
# Another way to call functions is with keyword arguments |
||||
add(y=6, x=5) # Keyword arguments can arrive in any order. |
||||
|
||||
# You can define functions that take a variable number of |
||||
# positional arguments |
||||
def varargs(*args): |
||||
return args |
||||
|
||||
varargs(1, 2, 3) # => (1, 2, 3) |
||||
|
||||
@ -1,5 +0,0 @@ |
||||
import numpy as np |
||||
|
||||
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) |
||||
|
||||
print(arr[1, 1:4]) |
||||
@ -1,14 +0,0 @@ |
||||
import panel as pn |
||||
|
||||
pn.extension() |
||||
|
||||
slider = pn.widgets.IntSlider(value=5, start=1, end=10) |
||||
|
||||
def model(n): |
||||
return "⭐" * n |
||||
|
||||
interactive_model = pn.bind(model, n=slider) |
||||
|
||||
layout = pn.Column(slider, interactive_model) |
||||
|
||||
layout.servable() # For deploying as a web app |
||||
@ -1,47 +0,0 @@ |
||||
# Example file showing a circle moving on screen |
||||
from lib2to3.fixer_util import is_tuple |
||||
|
||||
import pygame |
||||
|
||||
# pygame setup |
||||
pygame.init() |
||||
screen = pygame.display.set_mode((1280, 720)) |
||||
clock = pygame.time.Clock() |
||||
running = True |
||||
dt = 0 |
||||
|
||||
player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) |
||||
|
||||
while running: |
||||
# poll for events |
||||
# pygame.QUIT event means the user clicked X to close your window |
||||
for event in pygame.event.get(): |
||||
if event.type == pygame.QUIT: |
||||
running = False |
||||
|
||||
# fill the screen with a color to wipe away anything from last frame |
||||
screen.fill("purple") |
||||
|
||||
pygame.draw.circle(screen, "red", player_pos, 40) |
||||
|
||||
keys = pygame.key.get_pressed() |
||||
|
||||
if keys[pygame.K_w]: |
||||
player_pos.y -= 300 * dt |
||||
if keys[pygame.K_s]: |
||||
player_pos.y += 300 * dt |
||||
if keys[pygame.K_a]: |
||||
player_pos.x -= 300 * dt |
||||
if keys[pygame.K_d]: |
||||
player_pos.x += 300 * dt |
||||
|
||||
# flip() the display to put your work on screen |
||||
pygame.display.flip() |
||||
|
||||
# limits FPS to 60 |
||||
# dt is delta time in seconds since last frame, used for framerate- |
||||
# independent physics. |
||||
dt = clock.tick(60) / 1000 |
||||
|
||||
pygame.quit() |
||||
|
||||
@ -1,37 +0,0 @@ |
||||
from modelscope import AutoModelForCausalLM, AutoTokenizer |
||||
from modelscope import GenerationConfig |
||||
|
||||
# Note: The default behavior now has injection attack prevention off. |
||||
tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-14B-Chat", trust_remote_code=True) |
||||
|
||||
# use bf16 |
||||
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-14B-Chat", device_map="auto", trust_remote_code=True, bf16=True).eval() |
||||
# use fp16 |
||||
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-14B-Chat", device_map="auto", trust_remote_code=True, fp16=True).eval() |
||||
# use cpu only |
||||
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-14B-Chat", device_map="cpu", trust_remote_code=True).eval() |
||||
# use auto mode, automatically select precision based on the device. |
||||
model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-14B-Chat", device_map="auto", trust_remote_code=True).eval() |
||||
|
||||
# Specify hyperparameters for generation. But if you use transformers>=4.32.0, there is no need to do this. |
||||
# model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-14B-Chat", trust_remote_code=True) # 可指定不同的生成长度、top_p等相关超参 |
||||
|
||||
# 第一轮对话 1st dialogue turn |
||||
response, history = model.chat(tokenizer, "你好", history=None) |
||||
print(response) |
||||
# 你好!很高兴为你提供帮助。 |
||||
|
||||
# 第二轮对话 2nd dialogue turn |
||||
response, history = model.chat(tokenizer, "给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history) |
||||
print(response) |
||||
# 这是一个关于一个年轻人奋斗创业最终取得成功的故事。 |
||||
# 故事的主人公叫李明,他来自一个普通的家庭,父母都是普通的工人。从小,李明就立下了一个目标:要成为一名成功的企业家。 |
||||
# 为了实现这个目标,李明勤奋学习,考上了大学。在大学期间,他积极参加各种创业比赛,获得了不少奖项。他还利用课余时间去实习,积累了宝贵的经验。 |
||||
# 毕业后,李明决定开始自己的创业之路。他开始寻找投资机会,但多次都被拒绝了。然而,他并没有放弃。他继续努力,不断改进自己的创业计划,并寻找新的投资机会。 |
||||
# 最终,李明成功地获得了一笔投资,开始了自己的创业之路。他成立了一家科技公司,专注于开发新型软件。在他的领导下,公司迅速发展起来,成为了一家成功的科技企业。 |
||||
# 李明的成功并不是偶然的。他勤奋、坚韧、勇于冒险,不断学习和改进自己。他的成功也证明了,只要努力奋斗,任何人都有可能取得成功。 |
||||
|
||||
# 第三轮对话 3rd dialogue turn |
||||
response, history = model.chat(tokenizer, "给这个故事起一个标题", history=history) |
||||
print(response) |
||||
# 《奋斗创业:一个年轻人的成功之路》 |
||||
@ -1,10 +0,0 @@ |
||||
from math import ceil |
||||
|
||||
def chunk_into_n(lst, n): |
||||
size = ceil(len(lst) / n) |
||||
return list( |
||||
map(lambda x: lst[x * size:x * size + size], |
||||
list(range(n))) |
||||
) |
||||
|
||||
chunk_into_n([1, 2, 3, 4, 5, 6, 7], 4) # [[1, 2], [3, 4], [5, 6], [7]] |
||||
@ -1,7 +0,0 @@ |
||||
a = {'max': 200} |
||||
b = {'min': 100, 'max': 250} |
||||
c = {'min': 50} |
||||
|
||||
print(a['min']) |
||||
print(a['min'] + b['min'] + c['min']) # throws KeyError |
||||
print(a.get('min', 0) + b.get('min', 0) + c.get('min', 0)) # 150 |
||||
@ -1,6 +0,0 @@ |
||||
def capitalize(s, lower_rest=False, val3=3423): |
||||
return ''.join([s[:1].upper(), (s[1:].lower() if lower_rest else s[1:])]) |
||||
|
||||
|
||||
capitalize('fooBar') # 'FooBar' |
||||
capitalize('fooBar', True) # 'Foobar' |
||||
@ -1,15 +0,0 @@ |
||||
import sys |
||||
|
||||
a = [6, 7, 8, 9, 10] |
||||
|
||||
a[1] = 3 |
||||
b = a[2] |
||||
del a[3] |
||||
|
||||
print(a[1:4]) |
||||
del a[1:4] |
||||
|
||||
m = {'a': 1, 'b': 2, 'c': 3} |
||||
print(m['b']) |
||||
del m['b'] |
||||
c = m['c'] |
||||
@ -1,10 +0,0 @@ |
||||
<?php |
||||
$operator = PyCore::import("operator"); |
||||
$builtins = PyCore::import("builtins"); |
||||
|
||||
function varargs(...$xxx) { |
||||
return $xxx; |
||||
} |
||||
|
||||
|
||||
varargs(1, 2, 3); |
||||
@ -1,23 +0,0 @@ |
||||
from vllm_wrapper import vLLMWrapper |
||||
|
||||
model = vLLMWrapper('Qwen/Qwen-72B-Chat', tensor_parallel_size=2) |
||||
|
||||
import sys |
||||
|
||||
response, history = model.chat(query="你好", history=None) |
||||
print(response) |
||||
response, history = model.chat(query="给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history) |
||||
print(response) |
||||
response, history = model.chat(query="给这个故事起一个标题", history=history) |
||||
print(response) |
||||
|
||||
|
||||
def test(name, n, hello, **kwargs): |
||||
model2 = vLLMWrapper('Qwen/Qwen-72B-Chat', tensor_parallel_size=2) |
||||
|
||||
def it(m): |
||||
return "hello world" |
||||
|
||||
s = it(model2) |
||||
|
||||
return model2 |
||||
@ -1,119 +0,0 @@ |
||||
""" |
||||
This script creates an interactive web demo for the ChatGLM3-6B model using Gradio, a Python library for building quick and easy UI components for machine learning models. It's designed to showcase the capabilities of the ChatGLM3-6B model in a user-friendly interface, allowing users to interact with the model through a chat-like interface. |
||||
|
||||
Usage: |
||||
- Run the script to start the Gradio web server. |
||||
- Interact with the model by typing questions and receiving responses. |
||||
|
||||
Requirements: |
||||
- Gradio (required with 3.39 version, not support for 4.x), Transformers, and other necessary Python libraries should be installed. |
||||
- The model checkpoint should be accessible at the specified paths. |
||||
|
||||
Note: The script includes a modification to the Chatbot's postprocess method to handle markdown to HTML conversion, ensuring that the chat interface displays formatted text correctly. |
||||
""" |
||||
|
||||
import os |
||||
import mdtex2html |
||||
from transformers import AutoModel, AutoTokenizer |
||||
import gradio as gr |
||||
|
||||
MODEL_PATH = os.environ.get('MODEL_PATH', 'THUDM/chatglm3-6b') |
||||
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH) |
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH, trust_remote_code=True) |
||||
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True, device_map="auto").eval() |
||||
|
||||
def postprocess(self, y): |
||||
if y is None: |
||||
return [] |
||||
for i, (message, response) in enumerate(y): |
||||
y[i] = ( |
||||
None if message is None else mdtex2html.convert((message)), |
||||
None if response is None else mdtex2html.convert(response), |
||||
) |
||||
return y |
||||
|
||||
|
||||
gr.Chatbot.postprocess = postprocess |
||||
|
||||
|
||||
def parse_text(text): |
||||
"""copy from https://github.com/GaiZhenbiao/ChuanhuChatGPT/""" |
||||
lines = text.split("\n") |
||||
lines = [line for line in lines if line != ""] |
||||
count = 0 |
||||
for i, line in enumerate(lines): |
||||
if "```" in line: |
||||
count += 1 |
||||
items = line.split('`') |
||||
if count % 2 == 1: |
||||
lines[i] = f'<pre><code class="language-{items[-1]}">' |
||||
else: |
||||
lines[i] = f'<br></code></pre>' |
||||
else: |
||||
if i > 0: |
||||
if count % 2 == 1: |
||||
line = line.replace("`", "\`") |
||||
line = line.replace("<", "<") |
||||
line = line.replace(">", ">") |
||||
line = line.replace(" ", " ") |
||||
line = line.replace("*", "*") |
||||
line = line.replace("_", "_") |
||||
line = line.replace("-", "-") |
||||
line = line.replace(".", ".") |
||||
line = line.replace("!", "!") |
||||
line = line.replace("(", "(") |
||||
line = line.replace(")", ")") |
||||
line = line.replace("$", "$") |
||||
lines[i] = "<br>" + line |
||||
text = "".join(lines) |
||||
return text |
||||
|
||||
|
||||
def predict(input, chatbot, max_length, top_p, temperature, history, past_key_values): |
||||
chatbot.append((parse_text(input), "")) |
||||
for response, history, past_key_values in model.stream_chat(tokenizer, input, history, |
||||
past_key_values=past_key_values, |
||||
return_past_key_values=True, |
||||
max_length=max_length, top_p=top_p, |
||||
temperature=temperature): |
||||
chatbot[-1] = (parse_text(input), parse_text(response)) |
||||
|
||||
yield chatbot, history, past_key_values |
||||
|
||||
|
||||
def reset_user_input(): |
||||
return gr.update(value='') |
||||
|
||||
# |
||||
def reset_state(): |
||||
return [], [], None |
||||
|
||||
|
||||
with gr.Blocks() as demo: |
||||
gr.HTML("""<h1 align="center">ChatGLM3-6B</h1>""") |
||||
|
||||
chatbot = gr.Chatbot() |
||||
with gr.Row(): |
||||
with gr.Column(scale=4): |
||||
with gr.Column(scale=12): |
||||
user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10).style( |
||||
container=False) |
||||
with gr.Column(min_width=32, scale=1): |
||||
submitBtn = gr.Button("Submit", variant="primary") |
||||
with gr.Column(scale=1): |
||||
emptyBtn = gr.Button("Clear History") |
||||
max_length = gr.Slider(0, 32768, value=8192, step=1.0, label="Maximum length", interactive=True) |
||||
top_p = gr.Slider(0, 1, value=0.8, step=0.01, label="Top P", interactive=True) |
||||
temperature = gr.Slider(0, 1, value=0.6, step=0.01, label="Temperature", interactive=True) |
||||
|
||||
history = gr.State([]) |
||||
past_key_values = gr.State(None) |
||||
|
||||
submitBtn.click(predict, [user_input, chatbot, max_length, top_p, temperature, history, past_key_values], |
||||
[chatbot, history, past_key_values], show_progress=True) |
||||
submitBtn.click(reset_user_input, [], [user_input]) |
||||
|
||||
emptyBtn.click(reset_state, outputs=[chatbot, history, past_key_values], show_progress=True) |
||||
|
||||
demo.queue().launch(share=False, server_name="127.0.0.1", server_port=8501, inbrowser=True) |
||||
@ -1,22 +0,0 @@ |
||||
<?php |
||||
$operator = PyCore::import("operator"); |
||||
$builtins = PyCore::import("builtins"); |
||||
|
||||
function invert_dictionary($obj) { |
||||
return (function() { |
||||
$___ = []; |
||||
$___iter = $obj->items(); |
||||
foreach($___iter as $___i => [$key, $value]) { |
||||
$___[] = [$key, $value]; |
||||
} |
||||
return $___; |
||||
})(); |
||||
} |
||||
|
||||
|
||||
$ages = new PyDict([ |
||||
"Peter" => 10, |
||||
"Isabel" => 11, |
||||
"Anna" => 9, |
||||
]); |
||||
invert_dictionary($ages); |
||||
@ -1,9 +0,0 @@ |
||||
|
||||
from math import sqrt |
||||
|
||||
def is_prime(n): |
||||
if n <= 1 or (n % 2 == 0 and n > 2): |
||||
return False |
||||
return all(n % i for i in range(3, int(sqrt(n)) + 1, 2)) |
||||
|
||||
is_prime(11) # True |
||||
@ -1,5 +0,0 @@ |
||||
def varargs(*xxx): |
||||
return xxx |
||||
|
||||
|
||||
varargs(1, 2, 3) # => (1, 2, 3) |
||||
@ -1,8 +0,0 @@ |
||||
|
||||
def in_range(n, start, end = 0): |
||||
return start <= n <= end if end >= start else end <= n <= start |
||||
|
||||
in_range(3, 2, 5) # True |
||||
in_range(3, 4) # True |
||||
in_range(2, 3, 5) # False |
||||
in_range(3, 2) # False |
||||
@ -1,5 +0,0 @@ |
||||
|
||||
def find_last_index(lst, fn): |
||||
return len(lst) - 1 - next(i for i, x in enumerate(lst[::-1]) if fn(x)) |
||||
|
||||
find_last_index([1, 2, 3, 4], lambda n: n % 2 == 1) # 2 |
||||
@ -1,11 +0,0 @@ |
||||
|
||||
from collections import Counter |
||||
|
||||
def is_anagram(s1, s2): |
||||
return Counter( |
||||
c.lower() for c in s1 if c.isalnum() |
||||
) == Counter( |
||||
c.lower() for c in s2 if c.isalnum() |
||||
) |
||||
|
||||
is_anagram('#anagram', 'Nag a ram!') # True |
||||
@ -1,6 +0,0 @@ |
||||
|
||||
def none(lst, fn = lambda x: x): |
||||
return all(not fn(x) for x in lst) |
||||
|
||||
none([0, 1, 2, 0], lambda x: x >= 2 ) # False |
||||
none([0, 0, 0]) # True |
||||
@ -1,5 +0,0 @@ |
||||
|
||||
def weighted_average(nums, weights): |
||||
return sum(x * y for x, y in zip(nums, weights)) / sum(weights) |
||||
|
||||
weighted_average([1, 2, 3], [0.6, 0.2, 0.3]) # 1.72727 |
||||
@ -1,9 +0,0 @@ |
||||
|
||||
from math import sqrt |
||||
|
||||
def is_prime(n): |
||||
if n <= 1 or (n % 2 == 0 and n > 2): |
||||
return False |
||||
return all(n % i for i in range(3, int(sqrt(n)) + 1, 2)) |
||||
|
||||
is_prime(11) # True |
||||
@ -1,8 +0,0 @@ |
||||
|
||||
from time import sleep |
||||
|
||||
def delay(fn, ms, *args): |
||||
sleep(ms / 1000) |
||||
return fn(*args) |
||||
|
||||
delay(lambda x: print(x), 1000, 'later') # prints 'later' after one second |
||||
@ -1,6 +0,0 @@ |
||||
|
||||
def transpose(lst): |
||||
return list(zip(*lst)) |
||||
|
||||
transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) |
||||
# [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)] |
||||
@ -1,9 +0,0 @@ |
||||
|
||||
from functools import partial |
||||
|
||||
def curry(fn, *args): |
||||
return partial(fn, *args) |
||||
|
||||
add = lambda x, y: x + y |
||||
add10 = curry(add, 10) |
||||
add10(20) # 30 |
||||
@ -1,32 +0,0 @@ |
||||
<?php |
||||
if ($argc < 2) { |
||||
die("Usage: php conv.php [python-file]\n"); |
||||
} |
||||
|
||||
require __DIR__ . '/vendor/autoload.php'; |
||||
define('DEBUG', getenv('PY2PHP_DEBUG')); |
||||
define('STEP', getenv('PY2PHP_STEP')); |
||||
|
||||
$py_script = __DIR__ . '/dump.py'; |
||||
$result = shell_exec('python ' . $py_script . ' ' . $argv[1]); |
||||
$json = json_decode($result); |
||||
if (empty($json)) { |
||||
die("error py code"); |
||||
} |
||||
if ($json->_type != 'Module') { |
||||
echo "invalid python module\n"; |
||||
} |
||||
|
||||
error_reporting(E_ERROR); |
||||
// web or cli |
||||
if (!empty($argv[2])) { |
||||
$mode = $argv[2]; |
||||
} else { |
||||
$mode = 'cli'; |
||||
} |
||||
|
||||
$translator = new PhpAot\Python\Translator(); |
||||
$translator->setMode($mode); |
||||
$translator->setIndent(' '); |
||||
$translator->convert($json); |
||||
|
||||
@ -1,9 +0,0 @@ |
||||
import ast |
||||
import json |
||||
from ast2json import ast2json |
||||
import sys |
||||
|
||||
if __name__ == "__main__": |
||||
file_name = sys.argv[1] |
||||
tree = ast2json(ast.parse(open(file_name).read())) |
||||
print(json.dumps(tree, indent=4)) |
||||
@ -1,17 +0,0 @@ |
||||
<?php |
||||
$file = __DIR__ . '/cases/' . $_GET['file']; |
||||
|
||||
$op = empty($_GET['op']) ? 'conv' : $_GET['op']; |
||||
|
||||
switch ($op) { |
||||
case 'conv': |
||||
echo shell_exec('php conv.php ' . $file . ' web'); |
||||
break; |
||||
case 'dump': |
||||
echo shell_exec('python dump.py ' . $file); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
|
||||
@ -1,5 +0,0 @@ |
||||
<?php |
||||
return [ |
||||
'font-size' => '11', |
||||
'line-height' => '200', |
||||
]; |
||||
@ -1,28 +0,0 @@ |
||||
<select id="selectFont"> |
||||
<option>Roboto Mono</option> |
||||
<option>Consolas</option> |
||||
<option>Cascadia Mono</option> |
||||
<option>Inconsolata</option> |
||||
<option>Source Code Pro</option> |
||||
<option>IBM Plex Mono</option> |
||||
<option>Space Mono</option> |
||||
<option>PT Mono</option> |
||||
<option>Ubuntu Mono</option> |
||||
<option>Nanum Gothic Coding</option> |
||||
<option>Cousine</option> |
||||
<option>Fira Mono</option> |
||||
<option>Share Tech Mono</option> |
||||
<option>Courier Prime</option> |
||||
<option>Anonymous Pro</option> |
||||
<option>Cutive Mono</option> |
||||
<option>VT323</option> |
||||
<option>JetBrains Mono</option> |
||||
<option>Noto Sans Mono</option> |
||||
<option>Red Hat Mono</option> |
||||
<option>Martian Mono</option> |
||||
<option>Major Mono Display</option> |
||||
<option>Nova Mono</option> |
||||
<option>Syne Mono</option> |
||||
<option>Xanh Mono</option> |
||||
<option>Monofett</option> |
||||
</select> |
||||
@ -1,18 +0,0 @@ |
||||
<select id="selectLanguage" disabled="disabled"> |
||||
<?php if (false): ?> |
||||
<option value="language-html">HTML</option> |
||||
<option value="language-javascript">JavaScript</option> |
||||
<option value="language-python">Python</option> |
||||
<option value="language-java">Java</option> |
||||
<option value="language-csharp">C#</option> |
||||
<option value="language-php">PHP</option> |
||||
<option value="language-cpp">C++</option> |
||||
<option value="language-typescript">TypeScript</option> |
||||
<option value="language-ruby">Ruby</option> |
||||
<option value="language-swift">Swift</option> |
||||
<option value="language-kotlin">Kotlin</option> |
||||
<?php else: ?> |
||||
<option value="language-python">Python</option> |
||||
<option value="language-php">PHP</option> |
||||
<?php endif; ?> |
||||
</select> |
||||
@ -1,250 +0,0 @@ |
||||
<select id="selectStyle"> |
||||
<option selected="selected">a11y-dark.min.css</option> |
||||
<option>a11y-light.min.css</option> |
||||
<option>agate.min.css</option> |
||||
<option>an-old-hope.min.css</option> |
||||
<option>androidstudio.min.css</option> |
||||
<option>arduino-light.min.css</option> |
||||
<option>arta.min.css</option> |
||||
<option>ascetic.min.css</option> |
||||
<option>atom-one-dark-reasonable.min.css</option> |
||||
<option>atom-one-dark.min.css</option> |
||||
<option>atom-one-light.min.css</option> |
||||
<option>brown-paper.min.css</option> |
||||
<option>codepen-embed.min.css</option> |
||||
<option>color-brewer.min.css</option> |
||||
<option>dark.min.css</option> |
||||
<option>default.min.css</option> |
||||
<option>devibeans.min.css</option> |
||||
<option>docco.min.css</option> |
||||
<option>far.min.css</option> |
||||
<option>felipec.min.css</option> |
||||
<option>foundation.min.css</option> |
||||
<option>github-dark-dimmed.min.css</option> |
||||
<option>github-dark.min.css</option> |
||||
<option>github.min.css</option> |
||||
<option>gml.min.css</option> |
||||
<option>googlecode.min.css</option> |
||||
<option>gradient-dark.min.css</option> |
||||
<option>gradient-light.min.css</option> |
||||
<option>grayscale.min.css</option> |
||||
<option>hybrid.min.css</option> |
||||
<option>idea.min.css</option> |
||||
<option>intellij-light.min.css</option> |
||||
<option>ir-black.min.css</option> |
||||
<option>isbl-editor-dark.min.css</option> |
||||
<option>isbl-editor-light.min.css</option> |
||||
<option>kimbie-dark.min.css</option> |
||||
<option>kimbie-light.min.css</option> |
||||
<option>lightfair.min.css</option> |
||||
<option>lioshi.min.css</option> |
||||
<option>magula.min.css</option> |
||||
<option>mono-blue.min.css</option> |
||||
<option>monokai-sublime.min.css</option> |
||||
<option>monokai.min.css</option> |
||||
<option>night-owl.min.css</option> |
||||
<option>nnfx-dark.min.css</option> |
||||
<option>nnfx-light.min.css</option> |
||||
<option>nord.min.css</option> |
||||
<option>obsidian.min.css</option> |
||||
<option>panda-syntax-dark.min.css</option> |
||||
<option>panda-syntax-light.min.css</option> |
||||
<option>paraiso-dark.min.css</option> |
||||
<option>paraiso-light.min.css</option> |
||||
<option>pojoaque.min.css</option> |
||||
<option>purebasic.min.css</option> |
||||
<option>qtcreator-dark.min.css</option> |
||||
<option>qtcreator-light.min.css</option> |
||||
<option>rainbow.min.css</option> |
||||
<option>routeros.min.css</option> |
||||
<option>school-book.min.css</option> |
||||
<option>shades-of-purple.min.css</option> |
||||
<option>srcery.min.css</option> |
||||
<option>stackoverflow-dark.min.css</option> |
||||
<option>stackoverflow-light.min.css</option> |
||||
<option>sunburst.min.css</option> |
||||
<option>tokyo-night-dark.min.css</option> |
||||
<option>tokyo-night-light.min.css</option> |
||||
<option>tomorrow-night-blue.min.css</option> |
||||
<option>tomorrow-night-bright.min.css</option> |
||||
<option>vs.min.css</option> |
||||
<option>vs2015.min.css</option> |
||||
<option>xcode.min.css</option> |
||||
<option>xt256.min.css</option> |
||||
<option>base16/3024.min.css</option> |
||||
<option>base16/apathy.min.css</option> |
||||
<option>base16/apprentice.min.css</option> |
||||
<option>base16/ashes.min.css</option> |
||||
<option>base16/atelier-cave-light.min.css</option> |
||||
<option>base16/atelier-cave.min.css</option> |
||||
<option>base16/atelier-dune-light.min.css</option> |
||||
<option>base16/atelier-dune.min.css</option> |
||||
<option>base16/atelier-estuary-light.min.css</option> |
||||
<option>base16/atelier-estuary.min.css</option> |
||||
<option>base16/atelier-forest-light.min.css</option> |
||||
<option>base16/atelier-forest.min.css</option> |
||||
<option>base16/atelier-heath-light.min.css</option> |
||||
<option>base16/atelier-heath.min.css</option> |
||||
<option>base16/atelier-lakeside-light.min.css</option> |
||||
<option>base16/atelier-lakeside.min.css</option> |
||||
<option>base16/atelier-plateau-light.min.css</option> |
||||
<option>base16/atelier-plateau.min.css</option> |
||||
<option>base16/atelier-savanna-light.min.css</option> |
||||
<option>base16/atelier-savanna.min.css</option> |
||||
<option>base16/atelier-seaside-light.min.css</option> |
||||
<option>base16/atelier-seaside.min.css</option> |
||||
<option>base16/atelier-sulphurpool-light.min.css</option> |
||||
<option>base16/atelier-sulphurpool.min.css</option> |
||||
<option>base16/atlas.min.css</option> |
||||
<option>base16/bespin.min.css</option> |
||||
<option>base16/black-metal-bathory.min.css</option> |
||||
<option>base16/black-metal-burzum.min.css</option> |
||||
<option>base16/black-metal-dark-funeral.min.css</option> |
||||
<option>base16/black-metal-gorgoroth.min.css</option> |
||||
<option>base16/black-metal-immortal.min.css</option> |
||||
<option>base16/black-metal-khold.min.css</option> |
||||
<option>base16/black-metal-marduk.min.css</option> |
||||
<option>base16/black-metal-mayhem.min.css</option> |
||||
<option>base16/black-metal-nile.min.css</option> |
||||
<option>base16/black-metal-venom.min.css</option> |
||||
<option>base16/black-metal.min.css</option> |
||||
<option>base16/brewer.min.css</option> |
||||
<option>base16/bright.min.css</option> |
||||
<option>base16/brogrammer.min.css</option> |
||||
<option>base16/brush-trees-dark.min.css</option> |
||||
<option>base16/brush-trees.min.css</option> |
||||
<option>base16/chalk.min.css</option> |
||||
<option>base16/circus.min.css</option> |
||||
<option>base16/classic-dark.min.css</option> |
||||
<option>base16/classic-light.min.css</option> |
||||
<option>base16/codeschool.min.css</option> |
||||
<option>base16/colors.min.css</option> |
||||
<option>base16/cupcake.min.css</option> |
||||
<option>base16/cupertino.min.css</option> |
||||
<option>base16/danqing.min.css</option> |
||||
<option>base16/darcula.min.css</option> |
||||
<option>base16/dark-violet.min.css</option> |
||||
<option>base16/darkmoss.min.css</option> |
||||
<option>base16/darktooth.min.css</option> |
||||
<option>base16/decaf.min.css</option> |
||||
<option>base16/default-dark.min.css</option> |
||||
<option>base16/default-light.min.css</option> |
||||
<option>base16/dirtysea.min.css</option> |
||||
<option>base16/dracula.min.css</option> |
||||
<option>base16/edge-dark.min.css</option> |
||||
<option>base16/edge-light.min.css</option> |
||||
<option>base16/eighties.min.css</option> |
||||
<option>base16/embers.min.css</option> |
||||
<option>base16/equilibrium-dark.min.css</option> |
||||
<option>base16/equilibrium-gray-dark.min.css</option> |
||||
<option>base16/equilibrium-gray-light.min.css</option> |
||||
<option>base16/equilibrium-light.min.css</option> |
||||
<option>base16/espresso.min.css</option> |
||||
<option>base16/eva-dim.min.css</option> |
||||
<option>base16/eva.min.css</option> |
||||
<option>base16/flat.min.css</option> |
||||
<option>base16/framer.min.css</option> |
||||
<option>base16/fruit-soda.min.css</option> |
||||
<option>base16/gigavolt.min.css</option> |
||||
<option>base16/github.min.css</option> |
||||
<option>base16/google-dark.min.css</option> |
||||
<option>base16/google-light.min.css</option> |
||||
<option>base16/grayscale-dark.min.css</option> |
||||
<option>base16/grayscale-light.min.css</option> |
||||
<option>base16/green-screen.min.css</option> |
||||
<option>base16/gruvbox-dark-hard.min.css</option> |
||||
<option>base16/gruvbox-dark-medium.min.css</option> |
||||
<option>base16/gruvbox-dark-pale.min.css</option> |
||||
<option>base16/gruvbox-dark-soft.min.css</option> |
||||
<option>base16/gruvbox-light-hard.min.css</option> |
||||
<option>base16/gruvbox-light-medium.min.css</option> |
||||
<option>base16/gruvbox-light-soft.min.css</option> |
||||
<option>base16/hardcore.min.css</option> |
||||
<option>base16/harmonic16-dark.min.css</option> |
||||
<option>base16/harmonic16-light.min.css</option> |
||||
<option>base16/heetch-dark.min.css</option> |
||||
<option>base16/heetch-light.min.css</option> |
||||
<option>base16/helios.min.css</option> |
||||
<option>base16/hopscotch.min.css</option> |
||||
<option>base16/horizon-dark.min.css</option> |
||||
<option>base16/horizon-light.min.css</option> |
||||
<option>base16/humanoid-dark.min.css</option> |
||||
<option>base16/humanoid-light.min.css</option> |
||||
<option>base16/ia-dark.min.css</option> |
||||
<option>base16/ia-light.min.css</option> |
||||
<option>base16/icy-dark.min.css</option> |
||||
<option>base16/ir-black.min.css</option> |
||||
<option>base16/isotope.min.css</option> |
||||
<option>base16/kimber.min.css</option> |
||||
<option>base16/london-tube.min.css</option> |
||||
<option>base16/macintosh.min.css</option> |
||||
<option>base16/marrakesh.min.css</option> |
||||
<option>base16/materia.min.css</option> |
||||
<option>base16/material-darker.min.css</option> |
||||
<option>base16/material-lighter.min.css</option> |
||||
<option>base16/material-palenight.min.css</option> |
||||
<option>base16/material-vivid.min.css</option> |
||||
<option>base16/material.min.css</option> |
||||
<option>base16/mellow-purple.min.css</option> |
||||
<option>base16/mexico-light.min.css</option> |
||||
<option>base16/mocha.min.css</option> |
||||
<option>base16/monokai.min.css</option> |
||||
<option>base16/nebula.min.css</option> |
||||
<option>base16/nord.min.css</option> |
||||
<option>base16/nova.min.css</option> |
||||
<option>base16/ocean.min.css</option> |
||||
<option>base16/oceanicnext.min.css</option> |
||||
<option>base16/one-light.min.css</option> |
||||
<option>base16/onedark.min.css</option> |
||||
<option>base16/outrun-dark.min.css</option> |
||||
<option>base16/papercolor-dark.min.css</option> |
||||
<option>base16/papercolor-light.min.css</option> |
||||
<option>base16/paraiso.min.css</option> |
||||
<option>base16/pasque.min.css</option> |
||||
<option>base16/phd.min.css</option> |
||||
<option>base16/pico.min.css</option> |
||||
<option>base16/pop.min.css</option> |
||||
<option>base16/porple.min.css</option> |
||||
<option>base16/qualia.min.css</option> |
||||
<option>base16/railscasts.min.css</option> |
||||
<option>base16/rebecca.min.css</option> |
||||
<option>base16/ros-pine-dawn.min.css</option> |
||||
<option>base16/ros-pine-moon.min.css</option> |
||||
<option>base16/ros-pine.min.css</option> |
||||
<option>base16/sagelight.min.css</option> |
||||
<option>base16/sandcastle.min.css</option> |
||||
<option>base16/seti-ui.min.css</option> |
||||
<option>base16/shapeshifter.min.css</option> |
||||
<option>base16/silk-dark.min.css</option> |
||||
<option>base16/silk-light.min.css</option> |
||||
<option>base16/snazzy.min.css</option> |
||||
<option>base16/solar-flare-light.min.css</option> |
||||
<option>base16/solar-flare.min.css</option> |
||||
<option>base16/solarized-dark.min.css</option> |
||||
<option>base16/solarized-light.min.css</option> |
||||
<option>base16/spacemacs.min.css</option> |
||||
<option>base16/summercamp.min.css</option> |
||||
<option>base16/summerfruit-dark.min.css</option> |
||||
<option>base16/summerfruit-light.min.css</option> |
||||
<option>base16/synth-midnight-terminal-dark.min.css</option> |
||||
<option>base16/synth-midnight-terminal-light.min.css</option> |
||||
<option>base16/tango.min.css</option> |
||||
<option>base16/tender.min.css</option> |
||||
<option>base16/tomorrow-night.min.css</option> |
||||
<option>base16/tomorrow.min.css</option> |
||||
<option>base16/twilight.min.css</option> |
||||
<option>base16/unikitty-dark.min.css</option> |
||||
<option>base16/unikitty-light.min.css</option> |
||||
<option>base16/vulcan.min.css</option> |
||||
<option>base16/windows-10-light.min.css</option> |
||||
<option>base16/windows-10.min.css</option> |
||||
<option>base16/windows-95-light.min.css</option> |
||||
<option>base16/windows-95.min.css</option> |
||||
<option>base16/windows-high-contrast-light.min.css</option> |
||||
<option>base16/windows-high-contrast.min.css</option> |
||||
<option>base16/windows-nt-light.min.css</option> |
||||
<option>base16/windows-nt.min.css</option> |
||||
<option>base16/woodland.min.css</option> |
||||
<option>base16/xcode-dusk.min.css</option> |
||||
<option>base16/zenburn.min.css</option> |
||||
</select> |
||||
@ -1,16 +0,0 @@ |
||||
<h2>快捷键</h2> |
||||
<ol> |
||||
<li> |
||||
<p><strong>Enter</strong>:换行,并保持与上一行相同的缩进</p> |
||||
</li> |
||||
<li> |
||||
<p><strong>Tab</strong>/<strong>Shift</strong> + <strong>Tab</strong>:增加/减少缩进(支持多行)</p> |
||||
</li> |
||||
<li> |
||||
<p><strong>Shift</strong> + <strong>Del</strong> 或 <strong>Shift</strong> + <strong>Backspace</strong>:删除整行 |
||||
</p> |
||||
</li> |
||||
<li> |
||||
<p><strong>Home</strong>:将光标移到文本中的第一个非空格字符之前</p> |
||||
</li> |
||||
</ol> |
||||
@ -1,14 +0,0 @@ |
||||
<?php |
||||
$config = include ROOT_PATH . '/include/config.php'; |
||||
?> |
||||
|
||||
<p style="height: 36px"> |
||||
风格: |
||||
<?php include ROOT_PATH . '/include/style.php'; ?> |
||||
字体: |
||||
<?php include ROOT_PATH . '/include/font.php'; ?> |
||||
字体尺寸: |
||||
<input id="inputFontSize" type="number" step="1" value="<?= $config['font-size'] ?>" style="width: 40px;"/>
|
||||
行高 (%): |
||||
<input id="lineHeight" type="number" step="10" value="<?= $config['line-height'] ?>" style="width: 50px;"/>
|
||||
</p> |
||||
@ -1,29 +0,0 @@ |
||||
<?php |
||||
if (empty($_POST['code'])) { |
||||
die('require code'); |
||||
} |
||||
|
||||
define('ROOT_PATH', dirname(__DIR__, 2)); |
||||
|
||||
$id = date('Ymd_H_') . uniqid(); |
||||
|
||||
$py_file = ROOT_PATH . '/logs/' . $id . '.py'; |
||||
$php_file = ROOT_PATH . '/logs/' . $id . '.php'; |
||||
|
||||
file_put_contents($py_file, $_POST['code']); |
||||
$conv = ROOT_PATH . '/conv.php'; |
||||
|
||||
$cmd = 'php ' . $conv . ' ' . $py_file; |
||||
$code = shell_exec($cmd); |
||||
|
||||
echo json_encode([ |
||||
'data' => ['code' => $code,] |
||||
]); |
||||
|
||||
file_put_contents($php_file, $code); |
||||
|
||||
// 运行正常,删除历史文件 |
||||
if (str_starts_with($code, '<?php')) { |
||||
unlink($py_file); |
||||
unlink($php_file); |
||||
} |
||||
@ -1,31 +0,0 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en" xmlns=""> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Convert Python code to PHP</title> |
||||
</head> |
||||
<body> |
||||
<style> |
||||
iframe { |
||||
border: none; |
||||
} |
||||
|
||||
.code-iframe { |
||||
overflow-x: hidden; |
||||
overflow-y: hidden; |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
</style> |
||||
<iframe src="./input.php" id="iframe-input" class="code-iframe"></iframe> |
||||
<iframe src="./output.php" width="50%" id="iframe-output"></iframe> |
||||
<script> |
||||
const wsub = 60 |
||||
const hsub = 100 |
||||
document.getElementById('iframe-input').height = window.screen.height - hsub |
||||
document.getElementById('iframe-output').height = window.screen.height - hsub |
||||
document.getElementById('iframe-input').width = window.screen.width / 2 - wsub |
||||
document.getElementById('iframe-output').width = window.screen.width / 2 - wsub |
||||
</script> |
||||
</body> |
||||
</html> |
||||
@ -1,145 +0,0 @@ |
||||
<!DOCTYPE html> |
||||
|
||||
<html> |
||||
|
||||
<head> |
||||
<title>Convert Python code to PHP</title> |
||||
<style id="styleFont"> |
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400&display=swap'); |
||||
|
||||
#preCode code, |
||||
textarea, |
||||
#lineNumbers, |
||||
.lineNumbers { |
||||
font-family: "Roboto Mono", monospace; |
||||
font-weight: 400; |
||||
font-size: 12pt; |
||||
line-height: 150%; |
||||
} |
||||
|
||||
</style> |
||||
<link href="./static/css/style.css" rel="stylesheet"/> |
||||
<link id='theme1' href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/a11y-dark.min.css" |
||||
rel="stylesheet"/> |
||||
<script src="./static/js/codeEditorShortcutKeys.js" type="text/javascript"></script> |
||||
<script src="./static/js/jquery-1.10.2.js" type="text/javascript"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js" |
||||
type="text/javascript"></script> |
||||
</head> |
||||
|
||||
<body> |
||||
|
||||
<h1>PHP</h1> |
||||
<?php |
||||
define('ROOT_PATH', dirname(__DIR__)); |
||||
?> |
||||
|
||||
<?php include ROOT_PATH . '/include/toolbar.php'; ?> |
||||
|
||||
<div id="divCodeWrapper"> |
||||
<pre><code style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" class="lineNumbers"></code></pre> |
||||
<pre><code id="lineNumbers" style="opacity: 0.5;"></code></pre> |
||||
<pre id="preCode"><code id="codeBlock" class="language-php"></code></pre> |
||||
<textarea id="textarea1" wrap="soft" spellcheck="false"></textarea> |
||||
</div> |
||||
|
||||
<div style="margin-top: 8px"> |
||||
<button id="btn-copy" style="height: 32px; width: 90px">复制此代码</button> |
||||
</div> |
||||
|
||||
<script type="text/javascript"> |
||||
const textarea1 = document.getElementById("textarea1"); |
||||
const codeBlock = document.getElementById("codeBlock"); |
||||
const lineNumbers = document.getElementById('lineNumbers'); |
||||
|
||||
$('#btn-copy').click(function () { |
||||
navigator.clipboard.writeText(textarea1.value) |
||||
$('#btn-copy').attr('disabled', 'disabled').text('已复制代码') |
||||
}) |
||||
|
||||
$('#divCodeWrapper').css('height', (window.screen.height - 30) + 'px') |
||||
updateFont(); |
||||
|
||||
function updateLineNumbers() { |
||||
let lineCount = textarea1.value.split('\n').length; |
||||
let lines = ''; |
||||
for (let i = 1; i <= lineCount; i++) { |
||||
lines += i + '\n'; |
||||
} |
||||
lineNumbers.innerHTML = lines; |
||||
} |
||||
|
||||
// copy code from textarea to code block |
||||
function updateCode() { |
||||
let content = textarea1.value; |
||||
$('#btn-copy').removeAttr('disabled').text('复制此代码') |
||||
// encode the special characters |
||||
content = content.replace(/&/g, '&'); |
||||
content = content.replace(/</g, '<'); |
||||
content = content.replace(/>/g, '>'); |
||||
|
||||
// fill the encoded text to the code |
||||
codeBlock.innerHTML = content; |
||||
updateLineNumbers(); |
||||
|
||||
// call highlight.js to render the syntax highligtning |
||||
highlightJS(); |
||||
} |
||||
|
||||
// syntax highlight |
||||
function highlightJS() { |
||||
document.querySelectorAll('pre code').forEach((el) => { |
||||
hljs.highlightElement(el); |
||||
}); |
||||
} |
||||
|
||||
// sync the scroll bar position between textarea and code block |
||||
textarea1.addEventListener("scroll", () => { |
||||
codeBlock.scrollTop = textarea1.scrollTop; |
||||
codeBlock.scrollLeft = textarea1.scrollLeft; |
||||
lineNumbers.scrollTop = textarea1.scrollTop; |
||||
}); |
||||
|
||||
// change theme |
||||
document.getElementById("selectStyle").addEventListener("change", (e) => { |
||||
document.getElementById("theme1").href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/${e.target.value}`; |
||||
}); |
||||
|
||||
// change font |
||||
function updateFont() { |
||||
let selectFont = document.getElementById("selectFont"); |
||||
let fontName = selectFont.options[selectFont.selectedIndex].text; |
||||
let fontNameUrl = fontName.replace(" ", "+"); |
||||
let inputFontSize = document.getElementById("inputFontSize"); |
||||
let lineHeight = document.getElementById("lineHeight"); |
||||
|
||||
document.getElementById("styleFont").textContent = ` |
||||
@import url('https://fonts.googleapis.com/css2?&display=swap&family=${fontNameUrl}'); |
||||
pre, code, textarea, #lineNumbers, .lineNumbers { |
||||
font-family: "${fontName}", monospace; |
||||
font-size: ${inputFontSize.value}pt; |
||||
line-height: ${lineHeight.value}%; |
||||
}`; |
||||
} |
||||
|
||||
// change font size |
||||
document.getElementById("inputFontSize").addEventListener("input", () => { |
||||
updateFont(); |
||||
}); |
||||
|
||||
// change font |
||||
document.getElementById("selectFont").addEventListener("change", () => { |
||||
updateFont(); |
||||
}); |
||||
|
||||
// change line height |
||||
document.getElementById("lineHeight").addEventListener("input", () => { |
||||
updateFont(); |
||||
}); |
||||
|
||||
bindCodeEditorShortcutKeys(textarea1); |
||||
|
||||
</script> |
||||
</body> |
||||
|
||||
</html> |
||||
@ -1,60 +0,0 @@ |
||||
select { |
||||
height: 24px; |
||||
} |
||||
|
||||
#divCodeWrapper { |
||||
max-height: 800px; |
||||
width: 1200px; |
||||
overflow: hidden; |
||||
border: 1px solid #a5a5a5; |
||||
position: relative; |
||||
} |
||||
|
||||
#preCode { |
||||
height: 100%; |
||||
width: calc(100% - 50px); |
||||
position: absolute; |
||||
top: 0; |
||||
left: 50px; |
||||
overflow: hidden; |
||||
padding: 0; |
||||
margin: 0; |
||||
background: #1b1b1b; |
||||
border: none; |
||||
} |
||||
|
||||
#preCode code { |
||||
padding: 15px; |
||||
height: calc(100% - 30px); |
||||
width: calc(100% - 30px); |
||||
overflow-y: scroll; |
||||
overflow-x: auto; |
||||
} |
||||
|
||||
textarea { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 50px; |
||||
height: calc(100% - 30px); |
||||
width: calc(100% - 80px); |
||||
padding: 15px; |
||||
z-index: 2; |
||||
overflow-x: auto; |
||||
overflow-y: auto; |
||||
white-space: nowrap; |
||||
background-color: rgba(0, 0, 0, 0); |
||||
color: rgba(0, 0, 0, 0); |
||||
caret-color: white; |
||||
border: none; |
||||
outline: none; |
||||
border-left: 1px solid #383838; |
||||
} |
||||
|
||||
#lineNumbers { |
||||
position: absolute; |
||||
text-align: right; |
||||
top: 0; |
||||
left: 0; |
||||
height: calc(100% - 50px); |
||||
overflow: hidden; |
||||
} |
||||
@ -1,263 +0,0 @@ |
||||
function bindCodeEditorShortcutKeys(textarea) { |
||||
|
||||
// applying shortcut keys
|
||||
textarea.addEventListener('keydown', function (e) { |
||||
|
||||
// [Enter] key pressed detected
|
||||
if (e.key === 'Enter') { |
||||
|
||||
// Prevent the default behavior (new line)
|
||||
e.preventDefault(); |
||||
|
||||
// Get the cursor position
|
||||
var cursorPos = textarea.selectionStart; |
||||
|
||||
// Get the previous line
|
||||
var prevLine = textarea.value.substring(0, cursorPos).split('\n').slice(-1)[0]; |
||||
|
||||
// Get the indentation of the previous line
|
||||
var indent = prevLine.match(/^\s*/)[0]; |
||||
|
||||
// Add a new line with the same indentation
|
||||
textarea.setRangeText('\n' + indent, cursorPos, cursorPos, 'end'); |
||||
|
||||
// remove focus
|
||||
textarea.blur(); |
||||
|
||||
// regain focus (this is force the textarea scroll to caret position in case the caret falls out the textarea visible area)
|
||||
textarea.focus(); |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] pressed, but no [Shift]
|
||||
if (e.key === "Tab" && !e.shiftKey && |
||||
|
||||
// and no highlight detected
|
||||
textarea.selectionStart == textarea.selectionEnd) { |
||||
|
||||
// suspend default behaviour
|
||||
e.preventDefault(); |
||||
|
||||
// Get the current cursor position
|
||||
let cursorPosition = textarea.selectionStart; |
||||
|
||||
// Insert 4 white spaces at the cursor position
|
||||
let newValue = textarea.value.substring(0, cursorPosition) + " " + |
||||
textarea.value.substring(cursorPosition); |
||||
|
||||
// Update the textarea value and cursor position
|
||||
textarea.value = newValue; |
||||
textarea.selectionStart = textarea.selectionEnd = cursorPosition + 4; |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] and [Shift] keypress presence
|
||||
if (e.key === "Tab" && e.shiftKey && |
||||
|
||||
// no highlight detected
|
||||
textarea.selectionStart == textarea.selectionEnd) { |
||||
|
||||
// suspend default behaviour
|
||||
e.preventDefault(); |
||||
|
||||
// Get the current cursor position
|
||||
let cursorPosition = textarea.selectionStart; |
||||
|
||||
// Check the previous characters for spaces
|
||||
let leadingSpaces = 0; |
||||
for (let i = 0; i < 4; i++) { |
||||
if (textarea.value[cursorPosition - i - 1] === " ") { |
||||
leadingSpaces++; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (leadingSpaces > 0) { |
||||
// Remove the spaces
|
||||
let newValue = textarea.value.substring(0, cursorPosition - leadingSpaces) + |
||||
textarea.value.substring(cursorPosition); |
||||
|
||||
// Update the textarea value and cursor position
|
||||
textarea.value = newValue; |
||||
textarea.selectionStart = textarea.selectionEnd = cursorPosition - leadingSpaces; |
||||
} |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] key pressed and range selection detected
|
||||
if (e.key == 'Tab' & textarea.selectionStart != textarea.selectionEnd) { |
||||
e.preventDefault(); |
||||
|
||||
// split the textarea content into lines
|
||||
let lines = textarea.value.split('\n'); |
||||
|
||||
// find the start/end lines
|
||||
let startPos = textarea.value.substring(0, textarea.selectionStart).split('\n').length - 1; |
||||
let endPos = textarea.value.substring(0, textarea.selectionEnd).split('\n').length - 1; |
||||
|
||||
// calculating total removed white spaces
|
||||
// these values will be used for adjusting new cursor position
|
||||
let spacesRemovedFirstLine = 0; |
||||
let spacesRemoved = 0; |
||||
|
||||
// [Shift] key was pressed (this means we're un-indenting)
|
||||
if (e.shiftKey) { |
||||
|
||||
// iterate over all lines
|
||||
for (let i = startPos; i <= endPos; i++) { |
||||
|
||||
// /^ = from the start of the line,
|
||||
// {1,4} = remove in between 1 to 4 white spaces that may existed
|
||||
lines[i] = lines[i].replace(/^ {1,4}/, function (match) { |
||||
|
||||
// "match" is a string (white space) extracted
|
||||
|
||||
// obtaining total white spaces removed
|
||||
|
||||
// total white space removed at first line
|
||||
if (i == startPos) |
||||
spacesRemovedFirstLine = match.length; |
||||
|
||||
// total white space removed overall
|
||||
spacesRemoved += match.length; |
||||
|
||||
return ''; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// no shift key, so we're indenting
|
||||
else { |
||||
// iterate over all lines
|
||||
for (let i = startPos; i <= endPos; i++) { |
||||
// add a tab to the start of the line
|
||||
lines[i] = ' ' + lines[i]; // four spaces
|
||||
} |
||||
} |
||||
|
||||
// remember the cursor position
|
||||
let start = textarea.selectionStart; |
||||
let end = textarea.selectionEnd; |
||||
|
||||
// put the modified lines back into the textarea
|
||||
textarea.value = lines.join('\n'); |
||||
|
||||
// adjust the position of cursor start selection
|
||||
textarea.selectionStart = e.shiftKey ? |
||||
start - spacesRemovedFirstLine : start + 4; |
||||
|
||||
// adjust the position of cursor end selection
|
||||
textarea.selectionEnd = e.shiftKey ? |
||||
end - spacesRemoved : end + 4 * (endPos - startPos + 1); |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Shift] + [Del]/[Backspace] = Delete entire line(s)
|
||||
if (e.shiftKey && (e.key === "Delete" || e.key === "Backspace")) { |
||||
|
||||
e.preventDefault(); |
||||
|
||||
// find the start/end lines
|
||||
let startPos = textarea.value.substring(0, textarea.selectionStart).split('\n').length - 1; |
||||
let endPos = textarea.value.substring(0, textarea.selectionEnd).split('\n').length - 1; |
||||
|
||||
// get the line and the position in that line where the cursor is
|
||||
// pop() = take out the last line (which is the cursor selection start located)
|
||||
let cursorLine = textarea.value.substring(0, textarea.selectionStart).split('\n').pop(); |
||||
|
||||
// get the position of cursor within the last line
|
||||
let cursorPosInLine = cursorLine.length; |
||||
|
||||
// calculating total lines to be removed
|
||||
let totalLinesRemove = endPos - startPos + 1; |
||||
|
||||
// split the textarea content into lines
|
||||
let lines = textarea.value.split('\n'); |
||||
|
||||
// calculate new cursor position
|
||||
let newStart = lines.slice(0, startPos).join('\n').length + (startPos > 0 ? 1 : 0); |
||||
// add 1 if startPos > 0 to account for '\n' character
|
||||
|
||||
// remove the selected lines
|
||||
lines.splice(startPos, totalLinesRemove); |
||||
|
||||
// get the new line where the cursor will be after deleting lines
|
||||
// if lines[startPos] is not existed, then the new line will be an empty string
|
||||
let newLine = lines[startPos] || ''; |
||||
|
||||
// if the new line is shorter than the cursor position, put the cursor at the end of the line
|
||||
if (newLine.length < cursorPosInLine) { |
||||
cursorPosInLine = newLine.length; |
||||
} |
||||
|
||||
// adjuct the cursor's position in the line to the new cursor position
|
||||
newStart += cursorPosInLine; |
||||
|
||||
// put the modified lines back into the textarea
|
||||
textarea.value = lines.join('\n'); |
||||
|
||||
// set the new cursor position
|
||||
// both cursor selection start and end will be at the same position
|
||||
textarea.selectionStart = textarea.selectionEnd = newStart; |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
|
||||
return; |
||||
} |
||||
|
||||
// Move cursor to the first non-white space character
|
||||
if (e.key === "Home") { |
||||
|
||||
// get the line and the position in that line where the cursor is
|
||||
// pop() = take out the last line (which is the cursor selection start located)
|
||||
let line = textarea.value.substring(0, textarea.selectionStart).split('\n').pop(); |
||||
|
||||
// get the position of cursor within the last line
|
||||
let cursorPosInLine = line.length; |
||||
|
||||
// Find the start of the current line
|
||||
let lineStartPos = textarea.value.substring(0, textarea.selectionStart).lastIndexOf('\n') + 1; |
||||
|
||||
// Find the first non-whitespace character on the line
|
||||
let firstNonWhitespacePos = line.search(/\S/); |
||||
|
||||
// the cursor's position is already in front of first non-whitespace character,
|
||||
// or it's position is before first none-whitespace character,
|
||||
// move the cursor to the start of line
|
||||
if (firstNonWhitespacePos >= cursorPosInLine) { |
||||
// do nothing, perform default behaviour, which is moving the cursor to beginning of the line
|
||||
return true; |
||||
} |
||||
// If there's no non-whitespace character, this is an empty or whitespace-only line
|
||||
else if (firstNonWhitespacePos === -1) { |
||||
// do nothing, perform default behaviour, which is moving the cursor to beginning of the line
|
||||
return true; |
||||
} |
||||
|
||||
// Prevent the default Home key behavior
|
||||
e.preventDefault(); |
||||
|
||||
// Move the cursor to the position of the first non-whitespace character
|
||||
textarea.selectionStart = textarea.selectionEnd = lineStartPos + firstNonWhitespacePos; |
||||
|
||||
return; |
||||
} |
||||
|
||||
|
||||
}); |
||||
|
||||
} |
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue