fix(havuz): B2 — başarı sırası barajını geçemeyen adaya o bölüm önerilmesin [KARAR]
Havuz yalnız taban sırasına bakıyordu; hayal dilimi "adayın üstünde kapanan her şey" olduğu için barajın hemen dışındaki adaya tam da yazamayacağı bölümler düşüyordu (52.000 sıralı adaya tıp, 310.000'e mühendislik). Kaynak uydurma tablo değil: program_ozellik.min_basari_sirasi (YÖK Atlas API, 2026 kılavuzu; katalogdaki "baraj … sıra" satırı ve danışmanın tercihBaraji alanı da aynı kolonu okur). db.havuzAdaylari artık min_basari_sirasi < adayın sırası olan programları SQL'de çıkarır; barajı boş program süzülmez. Kanıt (havuzdaki baraj dışı program, önce → sonra): a04 4 → 0, a06 11 → 0, a08 11 → 0, p03 17 → 0; 40 profilin hepsinde 0. a07 (SÖZ 310.000, eğitim): alandaki programların tamamı barajlı olduğu için alan artık gerçekten gevşiyor (24 hayal → 5/13/6). Bilinen sınır: kolon bazı barajlı bölümlerde boş (ör. 16 tıp, 11 hukuk satırı) — veri işi, raporda. /meraklisina şeması (aday havuzu düğümü), 4. bölüm anlatımı, aria-label ve figcaption aynı kuralla güncellendi. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ flowchart TD
|
|||||||
A --> B("2. adım · İl seçimi<br/>programı olan tüm iller, seçtiğin alanlardaki program sayısına göre yeniden sayılır")
|
A --> B("2. adım · İl seçimi<br/>programı olan tüm iller, seçtiğin alanlardaki program sayısına göre yeniden sayılır")
|
||||||
B --> C("3. adım · Devlet / Vakıf<br/>sayılar hem alanı hem ili hesaba katar")
|
B --> C("3. adım · Devlet / Vakıf<br/>sayılar hem alanı hem ili hesaba katar")
|
||||||
C --> P("Danışmana söylediklerin<br/>öğretim dili, uzaktan/örgün, burs, yıllık ücret sınırı, evden uzaklık — sohbette söyleyip kaydettiklerin varsa havuzu bunlar da süzer")
|
C --> P("Danışmana söylediklerin<br/>öğretim dili, uzaktan/örgün, burs, yıllık ücret sınırı, evden uzaklık — sohbette söyleyip kaydettiklerin varsa havuzu bunlar da süzer")
|
||||||
P --> H("Aday havuzu<br/>elde kalan gerçek programlar — yalnızca en son tercih kılavuzunda yer alanlar<br/>kapanan ya da kodu değişip eski kaydı kalan programlar önerilmez<br/>yalnızca KKTC uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar da havuza girmez")
|
P --> H("Aday havuzu<br/>elde kalan gerçek programlar — yalnızca en son tercih kılavuzunda yer alanlar<br/>kapanan ya da kodu değişip eski kaydı kalan programlar önerilmez<br/>yalnızca KKTC uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar da havuza girmez<br/>sıralaman bir bölümün başarı sırası barajının gerisindeyse (tıp, hukuk, mühendislik, öğretmenlik gibi) o bölüm de girmez")
|
||||||
H --> S{"Havuzda 24'ten az program mı kaldı?"}
|
H --> S{"Havuzda 24'ten az program mı kaldı?"}
|
||||||
S -- "evet" --> G("Filtreler adım adım gevşetilir<br/>önce danışmana söylediklerin, sonra il, sonra alan — listede açıkça belirtilir<br/>seçimine uyan programlar havuzda kalır, boşluk sıralamana en yakın diğer programlarla dolar")
|
S -- "evet" --> G("Filtreler adım adım gevşetilir<br/>önce danışmana söylediklerin, sonra il, sonra alan — listede açıkça belirtilir<br/>seçimine uyan programlar havuzda kalır, boşluk sıralamana en yakın diğer programlarla dolar")
|
||||||
G --> H
|
G --> H
|
||||||
@@ -45,13 +45,13 @@ export function HuniSemasi() {
|
|||||||
return (
|
return (
|
||||||
<ElCizimiSema
|
<ElCizimiSema
|
||||||
tanim={SEMA}
|
tanim={SEMA}
|
||||||
ariaLabel="Sihirbaz akış şeması: sıralamanla açılan programlar alan, il ve devlet/vakıf adımlarıyla, danışmana söyleyip kaydettiğin tercihler (öğretim dili, uzaktan/örgün, burs, yıllık ücret sınırı, evden uzaklık) varsa onlarla da aday havuzuna daraltılır; havuza yalnızca en son tercih kılavuzunda yer alan programlar girer, kapanan ya da kodu değişip eski kaydı kalan programlar önerilmez, yalnızca KKTC uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar da havuza girmez; alanlar bölümün adına ve bağlı olduğu fakülteye göre belirlenir, il adımında programı olan tüm iller listelenir; havuz 24'ün altına düşerse filtreler önce danışmana söylediklerin, sonra il, sonra alan sırasıyla gevşetilir, gevşeyen seçimine uyan programlar havuzda kalır ve boşluk sıralamana en yakın diğer programlarla dolar, yine de dar kalırsa liste eldeki programlarla kurulur ve dağılım havuza uyarlanır; yapay zekâ havuzdan üstte hayal, ortada dengeli, sonda güvenli olacak şekilde en fazla 24 tercih seçip her satıra gerekçe yazar; risk notu ve trend özeti gerçek sıralama geçmişinden hesaplanır."
|
ariaLabel="Sihirbaz akış şeması: sıralamanla açılan programlar alan, il ve devlet/vakıf adımlarıyla, danışmana söyleyip kaydettiğin tercihler (öğretim dili, uzaktan/örgün, burs, yıllık ücret sınırı, evden uzaklık) varsa onlarla da aday havuzuna daraltılır; havuza yalnızca en son tercih kılavuzunda yer alan programlar girer, kapanan ya da kodu değişip eski kaydı kalan programlar önerilmez, yalnızca KKTC uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar da havuza girmez, sıralaman bir bölümün başarı sırası barajının gerisindeyse (tıp, hukuk, mühendislik, öğretmenlik gibi) o bölüm de girmez; alanlar bölümün adına ve bağlı olduğu fakülteye göre belirlenir, il adımında programı olan tüm iller listelenir; havuz 24'ün altına düşerse filtreler önce danışmana söylediklerin, sonra il, sonra alan sırasıyla gevşetilir, gevşeyen seçimine uyan programlar havuzda kalır ve boşluk sıralamana en yakın diğer programlarla dolar, yine de dar kalırsa liste eldeki programlarla kurulur ve dağılım havuza uyarlanır; yapay zekâ havuzdan üstte hayal, ortada dengeli, sonda güvenli olacak şekilde en fazla 24 tercih seçip her satıra gerekçe yazar; risk notu ve trend özeti gerçek sıralama geçmişinden hesaplanır."
|
||||||
figcaption={
|
figcaption={
|
||||||
<>
|
<>
|
||||||
Havuza yalnızca en son tercih kılavuzunda yer alan programlar girer;
|
Havuza yalnızca en son tercih kılavuzunda yer alan programlar girer;
|
||||||
kapanan ya da kodu değişip eski kaydı kalan programlar, yalnızca KKTC
|
kapanan ya da kodu değişip eski kaydı kalan programlar, yalnızca KKTC
|
||||||
uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar
|
uyruklulara ya da meslek lisesi mezunlarına ayrılmış kontenjanlar ve
|
||||||
önerilmez. Her
|
başarı sırası barajını geçemediğin bölümler önerilmez. Her
|
||||||
adım havuzu biraz daha daraltır; danışmana söyleyip kaydettiğin
|
adım havuzu biraz daha daraltır; danışmana söyleyip kaydettiğin
|
||||||
tercihler de (dil, ücret, uzaklık gibi) havuzu süzer. Yapay zekâ
|
tercihler de (dil, ücret, uzaklık gibi) havuzu süzer. Yapay zekâ
|
||||||
listeyi bu havuzun{" "}
|
listeyi bu havuzun{" "}
|
||||||
|
|||||||
@@ -127,7 +127,10 @@ export function MeraklisinaIcerik() {
|
|||||||
kalmış bir program sana önerilmez. Adında “KKTC
|
kalmış bir program sana önerilmez. Adında “KKTC
|
||||||
Uyruklu” ya da “M.T.O.K.” (meslek lisesi
|
Uyruklu” ya da “M.T.O.K.” (meslek lisesi
|
||||||
mezunlarına ayrılmış) yazan kontenjanlar da havuza girmez; onlar
|
mezunlarına ayrılmış) yazan kontenjanlar da havuza girmez; onlar
|
||||||
herkesin yazabileceği tercihler değildir. Aşağıdaki şema akışın
|
herkesin yazabileceği tercihler değildir. Tıp, hukuk, mühendislik
|
||||||
|
ya da öğretmenlik gibi başarı sırası barajı olan bölümlerde
|
||||||
|
sıralaman barajın gerisindeyse o bölümü tercih edemezsin; bu
|
||||||
|
yüzden o da havuza girmez. Aşağıdaki şema akışın
|
||||||
tamamını gösterir — havuz 24'ün altına düşerse filtrelerin hangi
|
tamamını gösterir — havuz 24'ün altına düşerse filtrelerin hangi
|
||||||
sırayla gevşetildiği (önce danışmana söylediklerin, sonra il,
|
sırayla gevşetildiği (önce danışmana söylediklerin, sonra il,
|
||||||
sonra alan), yine de yetmezse listenin eldeki programlarla, sana
|
sonra alan), yine de yetmezse listenin eldeki programlarla, sana
|
||||||
|
|||||||
@@ -89,6 +89,16 @@ export type OzellikSuzgeci = {
|
|||||||
|
|
||||||
let ozellikTablosuVar: boolean | null = null;
|
let ozellikTablosuVar: boolean | null = null;
|
||||||
|
|
||||||
|
function ozellikTablosuVarMi(): boolean {
|
||||||
|
if (ozellikTablosuVar == null) {
|
||||||
|
ozellikTablosuVar =
|
||||||
|
getDb()
|
||||||
|
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='program_ozellik'")
|
||||||
|
.get() !== undefined;
|
||||||
|
}
|
||||||
|
return ozellikTablosuVar;
|
||||||
|
}
|
||||||
|
|
||||||
function ozellikFiltreSql(o?: OzellikSuzgeci): { sql: string; args: (string | number)[] } {
|
function ozellikFiltreSql(o?: OzellikSuzgeci): { sql: string; args: (string | number)[] } {
|
||||||
if (!o) return { sql: "", args: [] };
|
if (!o) return { sql: "", args: [] };
|
||||||
const kosul: string[] = [];
|
const kosul: string[] = [];
|
||||||
@@ -104,19 +114,27 @@ function ozellikFiltreSql(o?: OzellikSuzgeci): { sql: string; args: (string | nu
|
|||||||
args.push(o.ucretUst);
|
args.push(o.ucretUst);
|
||||||
}
|
}
|
||||||
if (kosul.length === 0) return { sql: "", args: [] };
|
if (kosul.length === 0) return { sql: "", args: [] };
|
||||||
if (ozellikTablosuVar == null) {
|
if (!ozellikTablosuVarMi()) return { sql: "", args: [] };
|
||||||
ozellikTablosuVar =
|
|
||||||
getDb()
|
|
||||||
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='program_ozellik'")
|
|
||||||
.get() !== undefined;
|
|
||||||
}
|
|
||||||
if (!ozellikTablosuVar) return { sql: "", args: [] };
|
|
||||||
return {
|
return {
|
||||||
sql: `AND id IN (SELECT id FROM program_ozellik WHERE ${kosul.join(" AND ")})`,
|
sql: `AND id IN (SELECT id FROM program_ozellik WHERE ${kosul.join(" AND ")})`,
|
||||||
args,
|
args,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Başarı sırası barajı: `program_ozellik.min_basari_sirasi` programı tercih
|
||||||
|
* edebilmek için gereken en düşük sıradır (YÖK Atlas'tan, kılavuz yılına ait;
|
||||||
|
* ör. tıp 50.000). Adayın sırası bundan kötüyse o programı yazamaz. Barajı
|
||||||
|
* boş olan program (barajsız ya da veride eksik) süzülmez.
|
||||||
|
*/
|
||||||
|
function barajFiltreSql(sira: number): { sql: string; args: number[] } {
|
||||||
|
if (!ozellikTablosuVarMi()) return { sql: "", args: [] };
|
||||||
|
return {
|
||||||
|
sql: "AND id NOT IN (SELECT id FROM program_ozellik WHERE min_basari_sirasi < ?)",
|
||||||
|
args: [sira],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function uniturFiltreSql(grup?: UniturGrubu): { sql: string; args: string[] } {
|
function uniturFiltreSql(grup?: UniturGrubu): { sql: string; args: string[] } {
|
||||||
if (grup === "devlet") return { sql: "AND unitur = ?", args: ["DEVLET"] };
|
if (grup === "devlet") return { sql: "AND unitur = ?", args: ["DEVLET"] };
|
||||||
if (grup === "vakif")
|
if (grup === "vakif")
|
||||||
@@ -155,6 +173,8 @@ export function dilimAra(
|
|||||||
iller?: string[];
|
iller?: string[];
|
||||||
uniturGrubu?: UniturGrubu;
|
uniturGrubu?: UniturGrubu;
|
||||||
ozellik?: OzellikSuzgeci;
|
ozellik?: OzellikSuzgeci;
|
||||||
|
/** Adayın sırasıyla yazamayacağı (baraj dışı) programları çıkar */
|
||||||
|
barajDisiHaric?: boolean;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
} = {}
|
} = {}
|
||||||
@@ -176,16 +196,27 @@ export function dilimAra(
|
|||||||
: "";
|
: "";
|
||||||
const unitur = uniturFiltreSql(opts.uniturGrubu);
|
const unitur = uniturFiltreSql(opts.uniturGrubu);
|
||||||
const ozellik = ozellikFiltreSql(opts.ozellik);
|
const ozellik = ozellikFiltreSql(opts.ozellik);
|
||||||
|
const baraj = opts.barajDisiHaric
|
||||||
|
? barajFiltreSql(sira)
|
||||||
|
: { sql: "", args: [] };
|
||||||
|
|
||||||
const { alt, ust } = dilimAraligi(sira, dilim);
|
const { alt, ust } = dilimAraligi(sira, dilim);
|
||||||
if (ust != null && ust < alt) return { programlar: [], toplam: 0 };
|
if (ust != null && ust < alt) return { programlar: [], toplam: 0 };
|
||||||
const siraKosulu =
|
const siraKosulu =
|
||||||
ust != null ? `${EFEKTIF_SIRA} BETWEEN ? AND ?` : `${EFEKTIF_SIRA} >= ?`;
|
ust != null ? `${EFEKTIF_SIRA} BETWEEN ? AND ?` : `${EFEKTIF_SIRA} >= ?`;
|
||||||
const siraArgs = ust != null ? [alt, ust] : [alt];
|
const siraArgs = ust != null ? [alt, ust] : [alt];
|
||||||
const args = [tur, onlisans, ...illerListe, ...unitur.args, ...ozellik.args, ...siraArgs];
|
const args = [
|
||||||
|
tur,
|
||||||
|
onlisans,
|
||||||
|
...illerListe,
|
||||||
|
...unitur.args,
|
||||||
|
...ozellik.args,
|
||||||
|
...baraj.args,
|
||||||
|
...siraArgs,
|
||||||
|
];
|
||||||
|
|
||||||
const base = `FROM programs
|
const base = `FROM programs
|
||||||
WHERE tur = ? AND onlisans = ? ${ilFiltre} ${unitur.sql} ${ozellik.sql}
|
WHERE tur = ? AND onlisans = ? ${ilFiltre} ${unitur.sql} ${ozellik.sql} ${baraj.sql}
|
||||||
AND ${EFEKTIF_SIRA} IS NOT NULL
|
AND ${EFEKTIF_SIRA} IS NOT NULL
|
||||||
AND ${siraKosulu}`;
|
AND ${siraKosulu}`;
|
||||||
// hayal: sınıra en yakın (en büyük taban) önce; diğerleri en yakından uzağa
|
// hayal: sınıra en yakın (en büyük taban) önce; diğerleri en yakından uzağa
|
||||||
@@ -246,6 +277,7 @@ export function searchByRank(
|
|||||||
* alandan karışık geldiği için seçilen alan olduğundan az görünüyordu. Bu
|
* alandan karışık geldiği için seçilen alan olduğundan az görünüyordu. Bu
|
||||||
* yüzden havuz dilimin tamamını alır, alan/il süzgecini kendisi uygular ve
|
* yüzden havuz dilimin tamamını alır, alan/il süzgecini kendisi uygular ve
|
||||||
* en son kırpar (bkz. lib/rapor-havuzu.ts). En büyük puan türü ~9 bin satır.
|
* en son kırpar (bkz. lib/rapor-havuzu.ts). En büyük puan türü ~9 bin satır.
|
||||||
|
* Adayın başarı sırası barajını geçemediği programlar buraya hiç girmez.
|
||||||
*/
|
*/
|
||||||
export function havuzAdaylari(
|
export function havuzAdaylari(
|
||||||
sira: number,
|
sira: number,
|
||||||
@@ -253,7 +285,7 @@ export function havuzAdaylari(
|
|||||||
opts: { uniturGrubu?: UniturGrubu; ozellik?: OzellikSuzgeci } = {}
|
opts: { uniturGrubu?: UniturGrubu; ozellik?: OzellikSuzgeci } = {}
|
||||||
): Record<DilimKey, Program[]> {
|
): Record<DilimKey, Program[]> {
|
||||||
// LIMIT -1: SQLite'ta "sınırsız"
|
// LIMIT -1: SQLite'ta "sınırsız"
|
||||||
const ortak = { ...opts, limit: -1 };
|
const ortak = { ...opts, barajDisiHaric: true, limit: -1 };
|
||||||
return {
|
return {
|
||||||
hayal: dilimAra(sira, turKey, "hayal", ortak).programlar,
|
hayal: dilimAra(sira, turKey, "hayal", ortak).programlar,
|
||||||
dengeli: dilimAra(sira, turKey, "dengeli", ortak).programlar,
|
dengeli: dilimAra(sira, turKey, "dengeli", ortak).programlar,
|
||||||
|
|||||||
@@ -214,6 +214,9 @@ function dilimEkle(r: {
|
|||||||
* "24'ten az" kararı o alanda/ilde gerçekten kaç program olduğuna bakar.
|
* "24'ten az" kararı o alanda/ilde gerçekten kaç program olduğuna bakar.
|
||||||
* Bir filtre gevşediğinde ona uyan programlar havuzdan düşmez: önce onlar
|
* Bir filtre gevşediğinde ona uyan programlar havuzdan düşmez: önce onlar
|
||||||
* alınır, boşluk sıraya en yakın diğer programlarla dolar.
|
* alınır, boşluk sıraya en yakın diğer programlarla dolar.
|
||||||
|
*
|
||||||
|
* Adayın yazamayacağı programlar hiçbir basamakta havuza girmez: başarı
|
||||||
|
* sırası barajının gerisinde kaldığı bölümler ve özel kontenjan satırları.
|
||||||
*/
|
*/
|
||||||
export function havuzOlustur(
|
export function havuzOlustur(
|
||||||
params: RaporParams,
|
params: RaporParams,
|
||||||
@@ -242,7 +245,8 @@ export function havuzOlustur(
|
|||||||
// Bırakmazsa profil gevşetilir ve aşağıdaki sihirbaz akışı aynen sürer;
|
// Bırakmazsa profil gevşetilir ve aşağıdaki sihirbaz akışı aynen sürer;
|
||||||
// liste yine kurulur, gevşetme yapay zekâya ve adaya söylenir.
|
// liste yine kurulur, gevşetme yapay zekâya ve adaya söylenir.
|
||||||
const suzgec = profilSuzgeci(profil, iller.length > 0);
|
const suzgec = profilSuzgeci(profil, iller.length > 0);
|
||||||
// Dilimin tamamı; özel kontenjan satırları (KKTC uyruklu, M.T.O.K.) hariç
|
// Dilimin tamamı; adayın barajını geçemediği programlar (SQL) ve özel
|
||||||
|
// kontenjan satırları (KKTC uyruklu, M.T.O.K.) hariç
|
||||||
const adaylar = (ozellik?: OzellikSuzgeci) =>
|
const adaylar = (ozellik?: OzellikSuzgeci) =>
|
||||||
dilimEkle(
|
dilimEkle(
|
||||||
havuzAdaylari(params.sira, params.tur, { uniturGrubu, ozellik }),
|
havuzAdaylari(params.sira, params.tur, { uniturGrubu, ozellik }),
|
||||||
|
|||||||
Reference in New Issue
Block a user