From 7a716e7f5e2de4a98727776138be2e4e052efb42 Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Sat, 10 Jan 2026 00:43:54 +0800 Subject: [PATCH] t --- Dockerfile | 2 +- __pycache__/main.cpython-312.pyc | Bin 14148 -> 14747 bytes __pycache__/main.cpython-313.pyc | Bin 5408 -> 14854 bytes docker_deply.sh | 4 +- main.py | 69 ++++++++++++++++++------------- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7587a1e..808cb71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # 接收构建参数 BASE_IMAGE,由 docker_deply.sh 传入 ARG BASE_IMAGE=python:3.9-slim FROM ${BASE_IMAGE} - +# FROM docker.m.daocloud.io/python:3.9-slim # 设置工作目录 WORKDIR /app diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc index 229c646a00abdab46914060be52833317b9cb0ac..d4e429b9f9ba5607628a7e8779bfe8525dee0b71 100644 GIT binary patch delta 3000 zcmaJ>ZA@F&89v9pHvYz6U~Imw!AZD)3Faeh6Vil0p!tNvP%R`Wx%gZgJI1E>UN<4S z2qICHsAw}i+LkV>hNfvHBhyGNRsFF^X_|FE_Qx*SU`{kK?Z-4}n%p$gnjf2X?jO_T2XIBjMOUHN}{dWp`}sv92oJU8mcT42I7e;oYY(xWQG9$uao0-x`; zm1~WKWUXr-*M?p~FW-4(h1#+~Kx`2_Q03_x=^)|$SZvF%lX4!kpX-Rlcj~tII|qs_ zg`|h(R$oE|LBcB;B#mT}agni$ zP|4T}zGn`pA|Rx?SOUPbSuzW7K`WUTRSSBGXo;p6VUi;jQWTIhF*9KS4px=V5CF?_ z04o8oNEW2tN+457eVN=s0$D0q2&A0?)1}0xRDe@vu~Y_;KV+E$QfV(J-iGbXSY_@1 z#dllfqy9z$8%bb`+2jKamd=4Y)*>7P5)|~34N*#g3Z1qm1kzWBWa|YN&j4_NlsoO5 zE-c7=NGI8E0c7|<9VABs<>R5Q6gl%1P!B|9zQ`$k zfTtih2hwmsx&p4M&w(rOd5mQ{hH#9NogojwK$8#a&BHTf_0xlVG|5NB=rxWGN8|Bm zB0_T$lj0ODvSV>hAWB{k>4u4Df(|8936W9amC$41EtNpCJV$eHrr3D10zwN!;1Xh# zjmM|xh9Mb=4$xyGmjlofQAKTW~)+QXVRkTt< zk{9zOC>jpOqhtBfpmLZY?i4GA#yLK(;pNumwd~|1mq3ggbGBnue2<*8myo<(xjCbW z)I?rQy2~HO_iSFHA;cz76tN;F;3u{KV-=Gk8y|gf$axcYH7bbY0*;cXyqZ`9dB2#o zJMpBwqFN-vKJpX#$gXEW!490|vnMwQIrUVFe{T2d3|g~p_GrO^AK7=`MeV$1 zqqc4-@T0fV!JD@CUSDpTHxwvrbhPjDx23h|shrijv?ph6{L7J(Yi&cHHh$9n#bEHG z_Ir)FwxOcEIcMGbb-@L!&H{~7j@B6+usL&%u3XcBHAmN)wQKg+pQ`<9wv)MP|4q1R zTMgWGu14-w-(%JSC*JdBtNpXbv$m53Ezp#{GjM(2eaq~?Lu${LT3~W-menr7#fwXU zT-mN0hJpc9*JgF@zt%E02IgN&bENpJscM7XwG@9yx2H{cN9|MX45+MI_XKjDz^d;P z^F3+JGqmm*$$3WBJQvbE8&2P{I_GT4Iei5q@OBg|z+AI#^5smvrSWX*;q0#NKbVdb z9Dr^tQ~f(a)Zo zQUQx)7(RQ_0osS**N;ox_^z}3j1|~VLE$xWJU=k^wNjt@x;1_KRri^azE17^0438- zJ<)t-xAq&T&*~{cAE>PTrPKolMd;_9vj6A%_5CH9-)UigNybt3YY6)@*>Vh3{87wR ze9#pn@ca-Vd3Bsi@NW=~Dd9(DEhCeZOpr`CLh=UXB2LIxjt}Ek-3)v;Gwxo2@FVQ3 zJP1+dY~>{l?8g~;%qm0YbzzQN@nnMIhwv_Mz^FhSknu(_>kYw=Gr#rzOauEeu{{VX zA$+}TeP1Rb{&NEhNAY3iJbaq@F_TuoE7;#0g1a+|&Htug5Z?%#(JIA;@n+x~lb>v~Y2MH^W zMgDoP!0}`v(#Zs)&Qs#lBu5@F7iLp&F;9(i@yTl?tu4wQqv9*%a^r77MsZ=V8_`9;hd3>wmFck6Qjst@_mXA!byujrx-Fzf9L1z1)Eb@7+qUQ4^ z7NJq%rP%mk0+2T-CRr)uDTS&@wMt@K+37KUL7e1)B^*}a!<{YaN5Fy;oh#)*2)#=^ z1t71>JzptnA%^$vdv@Uw<=8a)=D)LU_T|jJY~c7q^NHEM4a%@ixpI{2rfx}C?adw< z$x^O|)cFmgZQWRvGghq`Yi4^lsnXg0cTQYCkyhVimVLisZZm(RItn&Gd6fD0KWEz$ A(*OVf delta 2502 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 EAH3s0r~m)} delta 2446 zcmZ`*U2Gf25#GHY{)wb%iWVta{F7u^j8s~GmP9$0)kZPm2(VMGStJmfD?^@SrX)|< zBMVzEbQ8C+fuc#f0TT4d4-JqOD3GE>kfK15MtTlx2uX$OPg*oV>o=mxLkk!|XO5y| zr|C+Z{dRU{ICuNaEWh8l{mAH^&*vd9K6|fF;Q>Paj*ISa?t{H|=#NI9ZzV~A4wBRR zN*-ix=3za|3m;!b<-LVqF5PuKoSDC%4ia{R1+o<6(X0${oS+G!h98R%z`aqzLIv+> zx#P$C*s&<#VTd?+5UF*5SYN@-!dZz$3i6D^`lIA|-qR9~pn2f3UfZY^8+uMRH;lTerzyvM6W@H2+acXtFP1fK7!5uT+EH`O;hJ4P-O}A?ux0ImG!z_wv@}c{NwxfJcyhAVioCgt!ts` zoE!Y!XAt>f+G}&ua&!{lJ?P-nuj(b>z2#bK>5bAAqmB?!v0Am{s$RF$Qq_P2+-NQX z-!1p!S4+BGpL`UQX$Qx~z_AfoG6c6%;mf$By6J#9X^#%SdrZB^OII{}D1I3>k@e;| zN?ha~xlY=iLGjz64<`QV^1kA^<@tfP?I7O3EAzMJUtQVhN!~uc)APumLdmyh-V5D% z=9_oZ&)yAbcYN9>V(i43!ZQ%+MY_B|Z+xwP*-ze&A$~tT26)Sjc*`>jc$*;Jre4H8 z8~Z)WbMkg1v^*tmk5j~7QPE~fMLZ`jFNm!Z(^4EuZPCFf&`=V^a7fC_;^Igj6idz} zejo0YNzQ|__;{oyHc$Fgsjlo>KE3o~Ur0Q8$|uuY7>Wf5EamzUh~0@~i$TdTH3Ovr zM8v*h4DN&px%g-qB(N!u3uF_|fv`LkXq3F6nJ-i= zPjjOT?GrI)u=zji@|LdXrEgd29eS;T2}U#j1HxvPk`%46i1=vi31{RF-qc-hN+ia! zbXU~I!-2a;7Vo$g|NTi%Xpd0UpyFra!)r34`zE$&pq7u`cr5Z*jBE`c-impaJ@VGc z$g(PLouh!ai3<8{RYmNP0b4Fjs}&(5ZPPiCvHvPd@M_>rfS(hDW2Z`|M11xt&4|}$ zM_QI#+}Pj~ptjVS(X2P@yTiVUIxqYwbi=#BEzm8yugP52L5E`JGD1;B`yp z%{m7P5pLgL_7&rLv}Tl>Reh0HU<133835UqDWxBa59h+i|4fem&Eb2ga$Rn_h%dJ5 z4dQ>Ge>c!4zA-=R{8vb#fwoJ0IG zx1|&{= str: """ Allocate a seat based on: 1. Even distribution (11 tables, max 12 per table) + - Prioritize filling empty tables first (min count) + - If counts are equal, fill sequentially (Table 1 before Table 2) 2. Mix industries (try to put user in a table where their industry is least represented) + - Uses natural language similarity to judge industry overlap """ TOTAL_TABLES = 11 MAX_PER_TABLE = 12 # Initialize table stats - # tables = { 1: {'count': 0, 'industries': []}, ... } tables = {i: {'count': 0, 'industries': []} for i in range(1, TOTAL_TABLES + 1)} # Fetch current seating status - # We join checkin_info with gsdh_data to get industries of people ALREADY SEATED + # Uses aggregation for efficiency as requested + # We use array_agg to collect industries for the diversity check in one query query = """ - SELECT ci.location, gd.industry_company + SELECT ci.location, COUNT(ci.gsdh_id), array_agg(gd.industry_company) FROM checkin_info ci - JOIN gsdh_data gd ON ci.gsdh_id = gd.new_id + LEFT JOIN gsdh_data gd ON ci.gsdh_id = gd.new_id WHERE ci.location IS NOT NULL AND ci.location LIKE '第%桌' + GROUP BY ci.location """ cur.execute(query) rows = cur.fetchall() for row in rows: - loc = row[0] # e.g. "第1桌" - ind = row[1] + loc = row[0] + count = row[1] + industries = row[2] if row[2] else [] + try: # Extract table number table_num = int(loc.replace("第", "").replace("桌", "")) if 1 <= table_num <= TOTAL_TABLES: - tables[table_num]['count'] += 1 - if ind: - tables[table_num]['industries'].append(ind) + tables[table_num]['count'] = count + # Filter out None values from industries + tables[table_num]['industries'] = [ind for ind in industries if ind] except ValueError: continue @@ -93,33 +100,39 @@ def assign_seat(cur, user_industry: str) -> str: if not available_tables: return "自由席" # Fallback if all full - # Strategy 1: Find tables with Minimum Count (Even Distribution) + # Strategy 1: Find tables with Minimum Count + # This automatically handles "Prioritize filling TOTAL_TABLES" because empty tables have count 0 min_count = min(t[1]['count'] for t in available_tables) - candidates_step1 = [t for t in available_tables if t[1]['count'] == min_count] + candidates = [t for t in available_tables if t[1]['count'] == min_count] - # Strategy 2: Among candidates, find best for diversity - # We want a table where user_industry is NOT present, or present least often - best_table = None + # Sort by table number to ensure sequential filling if counts are equal (Requirement: 顺序分配) + candidates.sort(key=lambda x: x[0]) - # If user has no industry info, just pick random from candidates + # Strategy 2: Optimize for Industry Diversity if not user_industry: - best_table = random.choice(candidates_step1)[0] + # If no industry info, just pick the first one (Sequential) + best_table = candidates[0][0] else: - # Score candidates: lower score is better (score = count of this industry in that table) + # Calculate similarity scores + # Score = sum of similarity with existing users + # Lower score is better (more unique) scored_candidates = [] - for table_id, stats in candidates_step1: - # Simple fuzzy check: count how many times user_industry appears in stats['industries'] - # We use simple string containment - industry_count = sum(1 for existing_ind in stats['industries'] if existing_ind and user_industry in existing_ind) - scored_candidates.append((table_id, industry_count)) - # Sort by industry count (asc) - scored_candidates.sort(key=lambda x: x[1]) + for table_id, stats in candidates: + total_similarity = 0.0 + for existing_ind in stats['industries']: + if existing_ind: + # Use difflib for fuzzy matching (0.0 to 1.0) + # This helps understand "Natural Language" industries better than exact match + sim = difflib.SequenceMatcher(None, user_industry, existing_ind).ratio() + total_similarity += sim + + scored_candidates.append((table_id, total_similarity)) - # Pick the one with least collision - min_collision = scored_candidates[0][1] - final_candidates = [x[0] for x in scored_candidates if x[1] == min_collision] - best_table = random.choice(final_candidates) + # Sort by similarity score (asc), then by table_id (asc) + scored_candidates.sort(key=lambda x: (x[1], x[0])) + + best_table = scored_candidates[0][0] return f"第{best_table}桌"