first commit

This commit is contained in:
kicap1992
2022-04-03 02:36:18 +08:00
commit 03f5abf96b
37 changed files with 10380 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
node_modules/
.next/
# python
__pycache__/
.env/

1
backend/app.py Normal file
View File

@ -0,0 +1 @@
print("ini try")

BIN
backend/berat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,17 @@
Usia,Berat,Keliling,Ukuran_batang,Jarak_duri,Keterangan
14,753,44,4.5,10.9,Masak
18,505,42,4,10,Masak
17,750,43,3,10,Masak
15,755,44,5,10,Masak
14,815,45,4.2,10,Masak
17,660,41.5,4.5,10,Masak
15,700,42,3,10,Masak
16,820,46,4,10,Masak
12,850,44,4.5,10,Mentah
11,830,42,4.2,10,Mentah
10,900,42,3,8.5,Mentah
9,900,30,2.5,7.5,Mentah
9,850,35,3,7.5,Mentah
13,800,40,3.9,9,Mentah
11,950,41,3.8,8.5,Mentah
13,860,40,4,9.5,Mentah
1 Usia Berat Keliling Ukuran_batang Jarak_duri Keterangan
2 14 753 44 4.5 10.9 Masak
3 18 505 42 4 10 Masak
4 17 750 43 3 10 Masak
5 15 755 44 5 10 Masak
6 14 815 45 4.2 10 Masak
7 17 660 41.5 4.5 10 Masak
8 15 700 42 3 10 Masak
9 16 820 46 4 10 Masak
10 12 850 44 4.5 10 Mentah
11 11 830 42 4.2 10 Mentah
12 10 900 42 3 8.5 Mentah
13 9 900 30 2.5 7.5 Mentah
14 9 850 35 3 7.5 Mentah
15 13 800 40 3.9 9 Mentah
16 11 950 41 3.8 8.5 Mentah
17 13 860 40 4 9.5 Mentah

View File

@ -0,0 +1,13 @@
Fungsi,Nama Variabel,Semesta Pembicaraan, Himpunan Fuzzy,Domain
Input,Usia,Sini semesta usia,Rendah,domain rendah usia
Input,Usia,Sini semesta usia,Tinggi,domain tinggi usia
Input,Berat,Sini semesta berat,Rendah,domain rendah berat
Input,Berat,Sini semesta berat,Tinggi,domain tinggi berat
Input,Keliling,Sini semesta keliling,Rendah,domain rendah keliling
Input,Keliling,Sini semesta keliling,Tinggi,domain tinggi keliling
Input,Ukurang Batang,Sini semesta ukuran batang,Rendah,domain rendah ukuran batang
Input,Ukurang Batang,Sini semesta ukuran batang,Tinggi,domain tinggi ukuran batang
Input,Jarak Duri,Sini semesta jarak duri,Rendah,domain rendah jarak duri
Input,Jarak Duri,Sini semesta jarak duri,Tinggi,domain tinggi jarak duri
Output,Keterangan,Sini semesta keterangan,Rendah (Mentah),domain rendah keterangan
Output,Keterangan,Sini semesta keterangan,Tinggi (Masak),domain tinggi keterangan
1 Fungsi Nama Variabel Semesta Pembicaraan Himpunan Fuzzy Domain
2 Input Usia Sini semesta usia Rendah domain rendah usia
3 Input Usia Sini semesta usia Tinggi domain tinggi usia
4 Input Berat Sini semesta berat Rendah domain rendah berat
5 Input Berat Sini semesta berat Tinggi domain tinggi berat
6 Input Keliling Sini semesta keliling Rendah domain rendah keliling
7 Input Keliling Sini semesta keliling Tinggi domain tinggi keliling
8 Input Ukurang Batang Sini semesta ukuran batang Rendah domain rendah ukuran batang
9 Input Ukurang Batang Sini semesta ukuran batang Tinggi domain tinggi ukuran batang
10 Input Jarak Duri Sini semesta jarak duri Rendah domain rendah jarak duri
11 Input Jarak Duri Sini semesta jarak duri Tinggi domain tinggi jarak duri
12 Output Keterangan Sini semesta keterangan Rendah (Mentah) domain rendah keterangan
13 Output Keterangan Sini semesta keterangan Tinggi (Masak) domain tinggi keterangan

33
backend/dataset/rule.csv Normal file
View File

@ -0,0 +1,33 @@
No,Rule,Usia,Berat,Keliling,Ukuran Batang,Jarak Duri,Keterangan
1,R1,Tinggi,Tinggi,Tinggi,Tinggi,Tinggi,Masak
2,R2,Tinggi,Tinggi,Tinggi,Tinggi,Rendah,Masak
3,R3,Tinggi,Tinggi,Tinggi,Rendah,Tinggi,Masak
4,R4,Tinggi,Tinggi,Tinggi,Rendah,Rendah,Masak
5,R5,Tinggi,Tinggi,Rendah,Tinggi,Tinggi,Masak
6,R6,Tinggi,Tinggi,Rendah,Tinggi,Rendah,Masak
7,R7,Tinggi,Tinggi,Rendah,Rendah,Tinggi,Masak
8,R8,Tinggi,Tinggi,Rendah,Rendah,Rendah,Mentah
9,R9,Tinggi,Rendah,Tinggi,Tinggi,Tinggi,Masak
10,R10,Tinggi,Rendah,Tinggi,Tinggi,Rendah,Masak
11,R11,Tinggi,Rendah,Tinggi,Rendah,Tinggi,Masak
12,R12,Tinggi,Rendah,Tinggi,Rendah,Rendah,Masak
13,R13,Tinggi,Rendah,Rendah,Tinggi,Tinggi,Masak
14,R14,Tinggi,Rendah,Rendah,Tinggi,Rendah,Masak
15,R15,Tinggi,Rendah,Rendah,Rendah,Tinggi,Masak
16,R16,Tinggi,Rendah,Rendah,Rendah,Rendah,Masak
17,R17,Rendah,Tinggi,Tinggi,Tinggi,Tinggi,Mentah
18,R18,Rendah,Tinggi,Tinggi,Tinggi,Rendah,Mentah
19,R19,Rendah,Tinggi,Tinggi,Rendah,Tinggi,Mentah
20,R20,Rendah,Tinggi,Tinggi,Rendah,Rendah,Mentah
21,R21,Rendah,Tinggi,Rendah,Tinggi,Tinggi,Mentah
22,R22,Rendah,Tinggi,Rendah,Tinggi,Rendah,Mentah
23,R23,Rendah,Tinggi,Rendah,Rendah,Tinggi,Mentah
24,R24,Rendah,Tinggi,Rendah,Rendah,Rendah,Mentah
25,R25,Rendah,Rendah,Tinggi,Tinggi,Tinggi,Masak
26,R26,Rendah,Rendah,Tinggi,Tinggi,Rendah,Mentah
27,R27,Rendah,Rendah,Tinggi,Rendah,Tinggi,Mentah
28,R28,Rendah,Rendah,Tinggi,Rendah,Rendah,Mentah
29,R29,Rendah,Rendah,Rendah,Tinggi,Tinggi,Mentah
30,R30,Rendah,Rendah,Rendah,Tinggi,Rendah,Mentah
31,R31,Rendah,Rendah,Rendah,Rendah,Tinggi,Mentah
32,R32,Rendah,Rendah,Rendah,Rendah,Rendah,Mentah
1 No Rule Usia Berat Keliling Ukuran Batang Jarak Duri Keterangan
2 1 R1 Tinggi Tinggi Tinggi Tinggi Tinggi Masak
3 2 R2 Tinggi Tinggi Tinggi Tinggi Rendah Masak
4 3 R3 Tinggi Tinggi Tinggi Rendah Tinggi Masak
5 4 R4 Tinggi Tinggi Tinggi Rendah Rendah Masak
6 5 R5 Tinggi Tinggi Rendah Tinggi Tinggi Masak
7 6 R6 Tinggi Tinggi Rendah Tinggi Rendah Masak
8 7 R7 Tinggi Tinggi Rendah Rendah Tinggi Masak
9 8 R8 Tinggi Tinggi Rendah Rendah Rendah Mentah
10 9 R9 Tinggi Rendah Tinggi Tinggi Tinggi Masak
11 10 R10 Tinggi Rendah Tinggi Tinggi Rendah Masak
12 11 R11 Tinggi Rendah Tinggi Rendah Tinggi Masak
13 12 R12 Tinggi Rendah Tinggi Rendah Rendah Masak
14 13 R13 Tinggi Rendah Rendah Tinggi Tinggi Masak
15 14 R14 Tinggi Rendah Rendah Tinggi Rendah Masak
16 15 R15 Tinggi Rendah Rendah Rendah Tinggi Masak
17 16 R16 Tinggi Rendah Rendah Rendah Rendah Masak
18 17 R17 Rendah Tinggi Tinggi Tinggi Tinggi Mentah
19 18 R18 Rendah Tinggi Tinggi Tinggi Rendah Mentah
20 19 R19 Rendah Tinggi Tinggi Rendah Tinggi Mentah
21 20 R20 Rendah Tinggi Tinggi Rendah Rendah Mentah
22 21 R21 Rendah Tinggi Rendah Tinggi Tinggi Mentah
23 22 R22 Rendah Tinggi Rendah Tinggi Rendah Mentah
24 23 R23 Rendah Tinggi Rendah Rendah Tinggi Mentah
25 24 R24 Rendah Tinggi Rendah Rendah Rendah Mentah
26 25 R25 Rendah Rendah Tinggi Tinggi Tinggi Masak
27 26 R26 Rendah Rendah Tinggi Tinggi Rendah Mentah
28 27 R27 Rendah Rendah Tinggi Rendah Tinggi Mentah
29 28 R28 Rendah Rendah Tinggi Rendah Rendah Mentah
30 29 R29 Rendah Rendah Rendah Tinggi Tinggi Mentah
31 30 R30 Rendah Rendah Rendah Tinggi Rendah Mentah
32 31 R31 Rendah Rendah Rendah Rendah Tinggi Mentah
33 32 R32 Rendah Rendah Rendah Rendah Rendah Mentah

347
backend/fuzzy.py Normal file
View File

@ -0,0 +1,347 @@
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import csv
import skfuzzy as fuzz
import asyncio
async def contoh_dulu(data_durian,anggota_usia,anggota_berat,anggota_keliling,anggota_ukuran_batang,anggota_jarak_duri,i):
# hitungan fuzzy tsukamoto berdasarkan rule base
df = pd.read_csv("dataset/rule.csv")
rule_length = len(df.index)
list_rule = df
hitungan_fuzzy_tsukamoto = []
for e in range(i):
ket_usia = "Tinggi" if anggota_usia[e][0] < anggota_usia[e][1] else "Rendah"
ket_berat = "Tinggi" if anggota_berat[e][0] < anggota_berat[e][1] else "Rendah"
ket_keliling = "Tinggi" if anggota_keliling[e][0] <= anggota_keliling[e][1] else "Rendah"
ket_ukuran_batang = "Tinggi" if anggota_ukuran_batang[e][0] <= anggota_ukuran_batang[e][1] else "Rendah"
ket_jarak_duri = "Tinggi" if anggota_jarak_duri[e][0] < anggota_jarak_duri[e][1] else "Rendah"
keterangan = None
for n in range(rule_length):
if str(list_rule.at[n,'Usia']) == ket_usia and str(list_rule.at[n,'Berat']) == ket_berat and str(list_rule.at[n,'Keliling']) == ket_keliling and str(list_rule.at[n,'Ukuran Batang']) == ket_ukuran_batang and str(list_rule.at[n,'Jarak Duri']) == ket_jarak_duri:
keterangan = str(list_rule.at[n,'Keterangan'])
data = {"No" : e, "Usia" : ket_usia, "Berat" : ket_berat, "Keliling" : ket_keliling,
"Ukuran Batang" : ket_ukuran_batang, "Jarak Duri" : ket_jarak_duri ,"Variable Linguistic" : keterangan,
"Keterangan" : data_durian.at[e,'Keterangan'], "MSE" : 0 if keterangan == data_durian.at[e,'Keterangan'] else 1
}
hitungan_fuzzy_tsukamoto.append(data)
await asyncio.sleep(0.1)
return(hitungan_fuzzy_tsukamoto)
def FungsiKeanggotaan(_range, _min , _hi, _nilai):
mini = fuzz.interp_membership(_range,_min,_nilai)
hi = fuzz.interp_membership(_range,_hi,_nilai)
# await asyncio.sleep(0.1)
return mini , hi
def RangeSubjektif(_low, _high, _step):
subjektif = np.arange(_low, _high , _step)
return subjektif
def FuzzyShow(_rule, _range_subjektif, _title, _pic_title):
lo = fuzz.trapmf(_range_subjektif, _rule[0])
hi = fuzz.trapmf(_range_subjektif, _rule[1])
fig,ax = plt.subplots(nrows=1, figsize=(7,3))
ax.plot(_range_subjektif, lo, 'g' , linewidth = 1.5 , label= "Mentah")
ax.plot(_range_subjektif, hi, 'r' , linewidth = 1.5 , label= "Masak")
ax.set_title(_title)
ax.legend()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.get_xaxis().tick_bottom()
ax.get_yaxis().tick_left()
plt.tight_layout()
plt.savefig(_pic_title+'.png')
# plt.show()
return lo, hi
def FuzzyShow1(_rule, _range_subjektif, _title,_pic_title):
lo = fuzz.trapmf(_range_subjektif, _rule[0])
hi = fuzz.trapmf(_range_subjektif, _rule[1])
fig,ax = plt.subplots(nrows=1, figsize=(7,3))
ax.plot(_range_subjektif, lo, 'r' , linewidth = 1.5 , label= "Masak")
ax.plot(_range_subjektif, hi, 'g' , linewidth = 1.5 , label= "Mentah")
ax.set_title(_title)
ax.legend()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.get_xaxis().tick_bottom()
ax.get_yaxis().tick_left()
plt.tight_layout()
plt.savefig(_pic_title+'.png')
# plt.show()
return lo, hi
def get_average(min,max) :
a = (min + max) / 2
return a
async def himpunan_fuzzy(min_usia,mid_usia,max_usia,min_berat,mid_berat,max_berat,min_keliling,mid_keliling,max_keliling,min_ukuran_batang,mid_ukuran_batang,max_ukuran_batang,min_jarak_duri,mid_jarak_duri,max_jarak_duri):
a = None
himpunan_fuzzy = pd.read_csv("dataset/himpunan_fuzzy.csv")
himpunan_fuzzy.loc[0, 'Semesta Pembicaraan'] = f"[ {min_usia} , {max_usia} ]" # Semesta pembicaraan (Rendah) Usia
himpunan_fuzzy.loc[1, 'Semesta Pembicaraan'] = f"[ {min_usia} , {max_usia} ]" # Semesta pembicaraan (Tinggi) Usia
himpunan_fuzzy.loc[0, 'Domain'] = f"[ {min_usia} , {mid_usia + 0.5} ]" # Domain (Rendah) Usia
himpunan_fuzzy.loc[1, 'Domain'] = f"[ {mid_usia - 0.5} , {max_usia} ]" # Domain pembicaraan (Tinggi) Usia
# Fuzzykasi Berat
himpunan_fuzzy.loc[2, 'Semesta Pembicaraan'] = f"[ {min_berat} , {max_berat} ]" # Semesta pembicaraan (Rendah) Berat
himpunan_fuzzy.loc[3, 'Semesta Pembicaraan'] = f"[ {min_berat} , {max_berat} ]" # Semesta pembicaraan (Tinggi) Berat
himpunan_fuzzy.loc[2, 'Domain'] = f"[ {min_berat} , {mid_berat + 10} ]" # Domain (Rendah) Berat
himpunan_fuzzy.loc[3, 'Domain'] = f"[ {mid_berat - 10} , {max_berat} ]" # Domain pembicaraan (Tinggi) Berat
# Fuzzykasi Keliling
himpunan_fuzzy.loc[4, 'Semesta Pembicaraan'] = f"[ {min_keliling} , {max_keliling} ]" # Semesta pembicaraan (Rendah) Keliling
himpunan_fuzzy.loc[5, 'Semesta Pembicaraan'] = f"[ {min_keliling} , {max_keliling} ]" # Semesta pembicaraan (Tinggi) Keliling
himpunan_fuzzy.loc[4, 'Domain'] = f"[ {min_keliling} , {mid_keliling + 1} ]" # Domain (Rendah) Keliling
himpunan_fuzzy.loc[5, 'Domain'] = f"[ {mid_keliling - 1} , {max_keliling} ]" # Domain pembicaraan (Tinggi) Keliling
# Fuzzykasi Keliling
himpunan_fuzzy.loc[4, 'Semesta Pembicaraan'] = f"[ {min_keliling} , {max_keliling} ]" # Semesta pembicaraan (Rendah) Keliling
himpunan_fuzzy.loc[5, 'Semesta Pembicaraan'] = f"[ {min_keliling} , {max_keliling} ]" # Semesta pembicaraan (Tinggi) Keliling
himpunan_fuzzy.loc[4, 'Domain'] = f"[ {min_keliling} , {mid_keliling + 1} ]" # Domain (Rendah) Keliling
himpunan_fuzzy.loc[5, 'Domain'] = f"[ {mid_keliling - 1} , {max_keliling} ]" # Domain pembicaraan (Tinggi) Keliling
# Fuzzykasi Ukuran Batang
himpunan_fuzzy.loc[6, 'Semesta Pembicaraan'] = f"[ {min_ukuran_batang} , {max_ukuran_batang} ]" # Semesta pembicaraan (Rendah) Ukuran Batang
himpunan_fuzzy.loc[7, 'Semesta Pembicaraan'] = f"[ {min_ukuran_batang} , {max_ukuran_batang} ]" # Semesta pembicaraan (Tinggi) Ukuran Batang
himpunan_fuzzy.loc[6, 'Domain'] = f"[ {min_ukuran_batang} , {mid_ukuran_batang + 0.5} ]" # Domain (Rendah) Ukuran Batang
himpunan_fuzzy.loc[7, 'Domain'] = f"[ {mid_ukuran_batang - 0.5} , {max_ukuran_batang} ]" # Domain pembicaraan (Tinggi) Ukuran Batang
# Fuzzykasi Jarak Duri
himpunan_fuzzy.loc[8, 'Semesta Pembicaraan'] = f"[ {min_jarak_duri} , {max_jarak_duri} ]" # Semesta pembicaraan (Rendah) Jarak Duri
himpunan_fuzzy.loc[9, 'Semesta Pembicaraan'] = f"[ {min_jarak_duri} , {max_jarak_duri} ]" # Semesta pembicaraan (Tinggi) Jarak Duri
himpunan_fuzzy.loc[8, 'Domain'] = f"[ {min_jarak_duri} , {mid_jarak_duri + 0.75} ]" # Domain (Rendah) Jarak Duri
himpunan_fuzzy.loc[9, 'Domain'] = f"[ {mid_jarak_duri - 0.25} , {max_jarak_duri} ]" # Domain pembicaraan (Tinggi) Jarak Duri
# Fuzzykasi Keterangan
himpunan_fuzzy.loc[10, 'Semesta Pembicaraan'] = f"[ 0 , 1 ]" # Semesta pembicaraan (Rendah) Keterangan
himpunan_fuzzy.loc[11, 'Semesta Pembicaraan'] = f"[ 0 , 1 ]" # Semesta pembicaraan (Tinggi) Keterangan
himpunan_fuzzy.loc[10, 'Domain'] = f"[ 0 , 0.5 ]" # Domain (Rendah) Keterangan
himpunan_fuzzy.loc[11, 'Domain'] = f"[ 0.5 , 1 ]" # Domain pembicaraan (Tinggi) Keterangan
# print(himpunan_fuzzy.to_dict())
himpunan_fuzzy.to_csv('out.csv',index=False)
with open("out.csv", "r") as f:
reader = csv.DictReader(f)
a = list(reader)
await asyncio.sleep(0.2)
# print(a)
return a
async def fuzzy(status, usianya = None , beratnya = None , kelilingnya = None , ukuran_batangnya = None , jarak_durinya = None):
dataset = None
data_durian = pd.read_csv("dataset/dataset.csv")
# await asyncio.sleep(0.5)
with open("dataset/dataset.csv", "r") as f:
reader = csv.DictReader(f)
dataset = list(reader)
await asyncio.sleep(0.1)
# data usia
data_usia = pd.DataFrame(data_durian)
data_usia = data_usia['Usia'].tolist()
_data_usia = data_usia
min_usia = min(data_usia) - 1
max_usia = max(data_usia) +1
mid_usia =np.median(data_usia)
await asyncio.sleep(0.1)
# data berat
data_berat = pd.DataFrame(data_durian)
data_berat = data_berat['Berat'].tolist()
_data_berat = data_berat
min_berat = min(data_berat) - 50
max_berat = max(data_berat) + 50
mid_berat =np.median(data_berat)
# data keliling
data_keliling = pd.DataFrame(data_durian)
data_keliling = data_keliling['Keliling'].tolist()
_data_keliling = data_keliling
min_keliling = min(data_keliling) - 1
max_keliling = max(data_keliling) + 1
# mid_keliling = get_average(min_keliling,max_keliling) #42.0
mid_keliling =np.median(data_keliling)
# data ukuran batang
data_ukuran_batang = pd.DataFrame(data_durian)
data_ukuran_batang = data_ukuran_batang['Ukuran_batang'].tolist()
_data_ukuran_batang = data_ukuran_batang
min_ukuran_batang = min(data_ukuran_batang) - 0.5
max_ukuran_batang = max(data_ukuran_batang) + 0.5
# mid_ukuran_batang = get_average(min_ukuran_batang,max_ukuran_batang) #4.0
mid_ukuran_batang = np.median(data_ukuran_batang)
# data jarak duri
data_jarak_duri = pd.DataFrame(data_durian)
data_jarak_duri = data_jarak_duri['Jarak_duri'].tolist()
_data_jarak_duri = data_jarak_duri
# print(data_jarak_duri)
min_jarak_duri = min(data_jarak_duri) - 0.5
max_jarak_duri = max(data_jarak_duri) + 0.5
mid_jarak_duri = get_average(min_jarak_duri,max_jarak_duri)#1.0
var_himpunan_fuzzy = await himpunan_fuzzy(min_usia,mid_usia,max_usia,min_berat,mid_berat,max_berat,min_keliling,mid_keliling,max_keliling,min_ukuran_batang,mid_ukuran_batang,max_ukuran_batang,min_jarak_duri,mid_jarak_duri,max_jarak_duri)
# fuzzy untuk field usia
x_usia = RangeSubjektif(min_usia , max_usia , 1)
r_usia = np.array([
[min_usia,min_usia,mid_usia,mid_usia],
[mid_usia,mid_usia,max_usia,max_usia]
])
lo_usia , hi_usia = FuzzyShow(r_usia , x_usia, 'Umur (minggu)',"usia")
# fuzzy untuk field berat
x_berat = RangeSubjektif(min_berat , max_berat , 1)
r_berat = np.array([
[min_berat,min_berat,mid_berat,mid_berat+10],
[mid_berat,mid_berat+10,max_berat,max_berat]
])
lo_berat , hi_berat = FuzzyShow1(r_berat , x_berat, 'Berat (kg)', "berat")
# fuzzy untuk field keliling
x_keliling = RangeSubjektif(min_keliling , max_keliling , 1)
r_keliling = np.array([
[min_keliling,min_keliling,mid_keliling,mid_keliling],
[mid_keliling,mid_keliling,max_keliling,max_keliling]
])
lo_keliling , hi_keliling = FuzzyShow(r_keliling , x_keliling, 'Keliling (cm)', "keliling")
# fuzzy untuk field ukuran batang
x_ukuran_batang = RangeSubjektif(min_ukuran_batang , max_ukuran_batang , 1)
r_ukuran_batang = np.array([
[min_ukuran_batang,min_ukuran_batang,mid_ukuran_batang,mid_ukuran_batang],
[mid_ukuran_batang,mid_ukuran_batang,max_ukuran_batang,max_ukuran_batang]
])
lo_ukuran_batang , hi_ukuran_batang = FuzzyShow(r_ukuran_batang , x_ukuran_batang, 'Keliling (cm)', "ukuran_batang")
# fuzzy untuk field jarak duri
x_jarak_duri = RangeSubjektif(min_jarak_duri , max_jarak_duri , 1)
r_jarak_duri = np.array([
[min_jarak_duri,min_jarak_duri,mid_jarak_duri,mid_jarak_duri],
[mid_jarak_duri,mid_jarak_duri,max_jarak_duri,max_jarak_duri]
])
lo_jarak_duri , hi_jarak_duri = FuzzyShow(r_jarak_duri , x_jarak_duri, 'Jarak Duri (mm)', "jarak_duri")
# Keanggotaan untuk usia
i = 0
anggota_usia = []
for usia in _data_usia:
ini_dia = FungsiKeanggotaan(x_usia,lo_usia,hi_usia,usia)
anggota_usia.append(ini_dia)
i = i+1
# print(anggota_usia)
# Keanggotaan untuk berat
anggota_berat = []
for berat in _data_berat:
ini_dia = FungsiKeanggotaan(x_berat,lo_berat,hi_berat,berat)
anggota_berat.append(ini_dia)
# Keanggotaan untuk keliling
anggota_keliling = []
for keliling in _data_keliling:
ini_dia = FungsiKeanggotaan(x_keliling,lo_keliling,hi_keliling,keliling)
anggota_keliling.append(ini_dia)
# Keanggotaan untuk ukuran batang
anggota_ukuran_batang = []
for ukuran_batang in _data_ukuran_batang:
ini_dia = FungsiKeanggotaan(x_ukuran_batang,lo_ukuran_batang,hi_ukuran_batang,ukuran_batang)
# print(ini_dia)
anggota_ukuran_batang.append(ini_dia)
# Keanggotaan untuk jarak duri
anggota_jarak_duri = []
for jarak_duri in _data_jarak_duri:
ini_dia = FungsiKeanggotaan(x_jarak_duri,lo_jarak_duri,hi_jarak_duri,jarak_duri)
anggota_jarak_duri.append(ini_dia)
rule_base = None
with open("dataset/rule.csv", "r") as f:
reader = csv.DictReader(f)
rule_base = list(reader)
keanggotaannya = await contoh_dulu(data_durian,anggota_usia,anggota_berat,anggota_keliling,anggota_ukuran_batang,anggota_jarak_duri,i)
# print(keanggotaannya)
data_usia = {'min':min_usia, 'max':max_usia}
data_berat = {'min':min_berat, 'max':max_berat}
data_keliling = {'min':min_keliling, 'max':max_keliling}
data_ukuran_batang = {'min':min_ukuran_batang, 'max':max_ukuran_batang}
data_jarak_duri = {'min':min_jarak_duri, 'max':max_jarak_duri}
detail_attribut = {'usia':data_usia, 'berat':data_berat, 'keliling':data_keliling, 'ukuran_batang':data_ukuran_batang, 'jarak_duri':data_jarak_duri}
if(status == 'ambil_dataset'):
context = {'detail_attribute':detail_attribut, 'rule_base':rule_base, 'keanggotaan':keanggotaannya, 'dataset' : dataset, 'himpunan_fuzzy' : var_himpunan_fuzzy}
elif (status == 'load_fuzzy'):
def hitungan_keterangan(usia,berat,keliling,ukuran_batang,jarak_duri):
df = pd.read_csv("dataset/rule.csv")
rule_length = len(df.index)
list_rule = df
keterangan = None
ket_usia = "Tinggi" if usia[0] < usia[1] else "Rendah"
ket_berat = "Tinggi" if berat[0] < berat[1] else "Rendah"
ket_keliling = "Tinggi" if keliling[0] <= keliling[1] else "Rendah"
ket_ukuran_batang = "Tinggi" if ukuran_batang[0] <= ukuran_batang[1] else "Rendah"
ket_jarak_duri = "Tinggi" if jarak_duri[0] < jarak_duri[1] else "Rendah"
for n in range(rule_length):
if str(list_rule.at[n,'Usia']) == ket_usia and str(list_rule.at[n,'Berat']) == ket_berat and str(list_rule.at[n,'Keliling']) == ket_keliling and str(list_rule.at[n,'Ukuran Batang']) == ket_ukuran_batang and str(list_rule.at[n,'Jarak Duri']) == ket_jarak_duri:
keterangan = str(list_rule.at[n,'Keterangan'])
break
return keterangan
usia = usianya
berat = beratnya
keliling = kelilingnya
ukuran_batang = ukuran_batangnya
jarak_duri = jarak_durinya
keanggotaan_usia = FungsiKeanggotaan(x_usia,lo_usia,hi_usia,usia)
print(keanggotaan_usia)
keanggotaan_berat = FungsiKeanggotaan(x_berat,lo_berat,hi_berat,berat)
print(keanggotaan_berat)
keanggotaan_keliling = FungsiKeanggotaan(x_keliling,lo_keliling,hi_keliling,keliling)
print(keanggotaan_keliling)
keanggotaan_ukuran_batang = FungsiKeanggotaan(x_ukuran_batang,lo_ukuran_batang,hi_ukuran_batang,ukuran_batang)
print(keanggotaan_ukuran_batang)
keanggotaan_jarak_duri =FungsiKeanggotaan(x_jarak_duri,lo_jarak_duri,hi_jarak_duri,jarak_duri)
print(keanggotaan_jarak_duri)
datanya = hitungan_keterangan(keanggotaan_usia,keanggotaan_berat,keanggotaan_keliling,keanggotaan_ukuran_batang,keanggotaan_jarak_duri)
context = datanya
# hitungan fuzzy tsukamoto berdasarkan data latih
return context

BIN
backend/jarak_duri.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
backend/keliling.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

67
backend/main.py Normal file
View File

@ -0,0 +1,67 @@
# from typing import Optional
import json
import os
from fastapi import FastAPI, Form, UploadFile , File , Request,HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fuzzy import fuzzy
# import asyncio
from fastapi.responses import FileResponse
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# create the fastapi api
@app.get("/")
async def read_root():
dataset = await fuzzy("ambil_dataset")
# dataset.update({"image_usia":FileResponse(image_usia)})
return dataset
# create post request
@app.post("/")
async def read_root_post(request: Request):
body = await request.form()
if body:
# check if body['data'] is not empty and not None
if body['data'] is not None and body['data'] != "":
json_data = json.loads(body['data'])
datanya = await fuzzy("load_fuzzy", json_data['usia'], json_data['berat'], json_data['keliling'], json_data['ukuran_batang'], json_data['jarak_duri'])
# print(datanya)
return {"ket": datanya}
else:
raise HTTPException(status_code=400, detail="data is empty")
else:
# print("ko")
raise HTTPException(status_code=404, detail="error")
# return {"message": "sini post datanya"}
# creata a image get
@app.get("/image/{image_name}")
async def read_image(image_name: str):
file_path = os.path.join("", image_name+'.png')
if os.path.exists(file_path):
return FileResponse(file_path)
else:
raise HTTPException(status_code=404, detail="File not found")
# image = await FileResponse(image_name+".png")
# return image
# create post method /fuzzy with form data and return the data
# @app.post("/fuzzy")
# async def read_item(nama: str = Form(...),
# umur: int = Form(...),
# alamat: str = Form(...),
# foto : UploadFile = File(...)):
# return {"nama": nama, "umur": umur, "alamat": alamat, "foto": foto}

13
backend/out.csv Normal file
View File

@ -0,0 +1,13 @@
Fungsi,Nama Variabel,Semesta Pembicaraan, Himpunan Fuzzy,Domain
Input,Usia,"[ 8 , 19 ]",Rendah,"[ 8 , 14.0 ]"
Input,Usia,"[ 8 , 19 ]",Tinggi,"[ 13.0 , 19 ]"
Input,Berat,"[ 455 , 1000 ]",Rendah,"[ 455 , 827.5 ]"
Input,Berat,"[ 455 , 1000 ]",Tinggi,"[ 807.5 , 1000 ]"
Input,Keliling,"[ 29.0 , 47.0 ]",Rendah,"[ 29.0 , 43.0 ]"
Input,Keliling,"[ 29.0 , 47.0 ]",Tinggi,"[ 41.0 , 47.0 ]"
Input,Ukurang Batang,"[ 2.0 , 5.5 ]",Rendah,"[ 2.0 , 4.5 ]"
Input,Ukurang Batang,"[ 2.0 , 5.5 ]",Tinggi,"[ 3.5 , 5.5 ]"
Input,Jarak Duri,"[ 7.0 , 11.4 ]",Rendah,"[ 7.0 , 9.95 ]"
Input,Jarak Duri,"[ 7.0 , 11.4 ]",Tinggi,"[ 8.95 , 11.4 ]"
Output,Keterangan,"[ 0 , 1 ]",Rendah (Mentah),"[ 0 , 0.5 ]"
Output,Keterangan,"[ 0 , 1 ]",Tinggi (Masak),"[ 0.5 , 1 ]"
1 Fungsi Nama Variabel Semesta Pembicaraan Himpunan Fuzzy Domain
2 Input Usia [ 8 , 19 ] Rendah [ 8 , 14.0 ]
3 Input Usia [ 8 , 19 ] Tinggi [ 13.0 , 19 ]
4 Input Berat [ 455 , 1000 ] Rendah [ 455 , 827.5 ]
5 Input Berat [ 455 , 1000 ] Tinggi [ 807.5 , 1000 ]
6 Input Keliling [ 29.0 , 47.0 ] Rendah [ 29.0 , 43.0 ]
7 Input Keliling [ 29.0 , 47.0 ] Tinggi [ 41.0 , 47.0 ]
8 Input Ukurang Batang [ 2.0 , 5.5 ] Rendah [ 2.0 , 4.5 ]
9 Input Ukurang Batang [ 2.0 , 5.5 ] Tinggi [ 3.5 , 5.5 ]
10 Input Jarak Duri [ 7.0 , 11.4 ] Rendah [ 7.0 , 9.95 ]
11 Input Jarak Duri [ 7.0 , 11.4 ] Tinggi [ 8.95 , 11.4 ]
12 Output Keterangan [ 0 , 1 ] Rendah (Mentah) [ 0 , 0.5 ]
13 Output Keterangan [ 0 , 1 ] Tinggi (Masak) [ 0.5 , 1 ]

BIN
backend/requirements.txt Normal file

Binary file not shown.

BIN
backend/ukuran_batang.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
backend/usia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

3
frontend/.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

34
frontend/README.md Normal file
View File

@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

View File

@ -0,0 +1,239 @@
import classess from "./InputData.module.css";
import Card from "../ui/Card";
function DataSet(props) {
let status = props.data.status;
let table_dataset,himpunan_fuzzy,url,table_rule_base,table_keanggotaan
if (status == "error") {
console.log("error")
}else{
console.log(props.data)
let dataset = props.data.dataset;
let rule_base = props.data.rule_base;
let keanggotaan = props.data.keanggotaan;
// create a variable table_dataset table from dataset where first column is id, second column is Usia("Minggu"), third column is Berat("gram"), fourth column is Keliling(cm), fifth column is Ukuran Batang(cm), sixth column is Jarak Duri(mm)
table_dataset = dataset.map((item, index) => {
return (
<tr key={index}>
<td>{index}</td>
<td>{item.Usia}</td>
<td>{item.Berat}</td>
<td>{item.Keliling}</td>
<td>{item.Ukuran_batang}</td>
<td>{item.Jarak_duri}</td>
<td>{item.Keterangan}</td>
</tr>
);
});
himpunan_fuzzy = props.data.himpunan_fuzzy;
url = "http://127.0.0.1:5000/";
table_rule_base = rule_base.map((item, index) => {
return (
<tr key={index}>
<td>{item.No}</td>
<td>{item.Rule}</td>
<td>{item.Usia}</td>
<td>{item.Berat}</td>
<td>{item.Keliling}</td>
<td>{item['Ukuran Batang']}</td>
<td>{item['Jarak Duri']}</td>
<td>{item.Keterangan}</td>
</tr>
);
})
table_keanggotaan = keanggotaan.map((item, index) => {
return (
<tr key={index}>
<td>{item.No}</td>
<td>{item.Usia}</td>
<td>{item.Berat}</td>
<td>{item.Keliling}</td>
<td>{item['Ukuran Batang']}</td>
<td>{item['Jarak Duri']}</td>
<td>{item['Variable Linguistic']}</td>
<td>{item.Keterangan}</td>
</tr>
);
})
}
return (
<Card>
<form className={classess.form} >
<div className={classess.control}>
<h2 htmlFor="title">DataSet</h2>
<div id="div_dataset" >
<table id="table_dataset" className={classess.table}>
<thead>
<tr>
<th>ID</th>
<th>Usia <br /> ( <i>Minggu</i> )</th>
<th>Berat <br /> ( <i>gram</i> )</th>
<th>Keliling <br /> ( <i>cm</i> ) </th>
<th>Ukuran Batang <br /> ( <i>cm</i> ) </th>
<th>Jarak Duri <br /> ( <i>mm</i> ) </th>
<th>Keterangan</th>
</tr>
</thead>
<tbody>
{table_dataset}
</tbody>
</table>
</div>
</div>
<br />
<hr />
<div className={classess.control}>
<h2 htmlFor="image">Semesta Pembicaraan</h2>
<div id="div_himpunan_fuzzy" >
<table id="table_himpunan_fuzzy" className={classess.table}>
<thead>
<tr>
<th>Fungsi</th>
<th>Nama Variabel</th>
<th>Semesta Pembicaraan</th>
<th>Himpunan Fuzzy</th>
<th>Domain</th>
</tr>
</thead>
<tbody>
<tr>
<td rowSpan={10}>Input</td>
<td rowSpan={2}>Usia <br /> <i>(Minggu)</i> </td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[0]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[0][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[0]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[1][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[1]['Domain']}</i></b> </td>
</tr>
<tr>
<td rowSpan={2}>Berat <br /> <i>(gram)</i></td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[2]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[2][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[2]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[3][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[3]['Domain']}</i></b> </td>
</tr>
<tr>
<td rowSpan={2}>Keliling <br /> <i>(cm)</i></td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[4]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[4][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[4]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[5][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[5]['Domain']}</i></b> </td>
</tr>
<tr>
<td rowSpan={2}>Ukuran Batang <br /> <i>(cm)</i></td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[6]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[6][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[6]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[7][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[7]['Domain']}</i></b> </td>
</tr>
<tr>
<td rowSpan={2}>Jarak Duri <br /> <i>(mm)</i></td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[8]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[8][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[8]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[9][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[9]['Domain']}</i></b> </td>
</tr>
<tr>
<td rowSpan={2}>Output</td>
<td rowSpan={2}>Keterangan</td>
<td rowSpan={2}> <b><i>{himpunan_fuzzy[10]['Semesta Pembicaraan']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[10][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[10]['Domain']}</i></b> </td>
</tr>
<tr>
<td> <b><i>{himpunan_fuzzy[11][' Himpunan Fuzzy']}</i></b> </td>
<td> <b><i>{himpunan_fuzzy[11]['Domain']}</i></b> </td>
</tr>
</tbody>
</table>
</div>
</div>
<br /><hr />
<div className={classess.control}>
<h2 htmlFor="address">Himpunan <i>Fuzzy</i></h2>
<center><h3><i>Fuzzy</i> Usia</h3></center>
<img src={url+"image/usia"} className={classess.image} />
<center><h3><i>Fuzzy</i> Berat</h3></center>
<img src={url+"image/berat"} className={classess.image} />
<center><h3><i>Fuzzy</i> Keliling</h3></center>
<img src={url+"image/keliling"} className={classess.image} />
<center><h3><i>Fuzzy</i> Ukuran Batang</h3></center>
<img src={url+"image/ukuran_batang"} className={classess.image} />
<center><h3><i>Fuzzy</i> Jarak Duri</h3></center>
<img src={url+"image/jarak_duri"} className={classess.image} />
</div>
<br /><hr />
<div className={classess.control}>
<h2 htmlFor="description">Rule Base</h2>
<div id="div_rule_base" >
<table className={classess.table}>
<thead>
<tr>
<th>No</th>
<th>Rule</th>
<th>Usia</th>
<th>Berat</th>
<th>Keliling</th>
<th>Ukuran Batang</th>
<th>Jarak Duri</th>
<th>Keterangan</th>
</tr>
</thead>
<tbody>
{table_rule_base}
</tbody>
</table>
</div>
</div>
<br /><hr />
<div className={classess.control}>
<h2 htmlFor="description">Keanggotaan Data</h2>
<div id="div_keanggotaan" >
<table className={classess.table}>
<thead>
<tr>
<th>No</th>
<th>Usia</th>
<th>Berat</th>
<th>Keliling</th>
<th>Ukuran <br /> Batang</th>
<th>Jarak <br /> Duri</th>
<th>Variable <br />Linguistic</th>
<th>Keterangan</th>
</tr>
</thead>
<tbody>
{table_keanggotaan}
</tbody>
</table>
</div>
</div>
</form>
</Card>
);
}
export default DataSet;

View File

@ -0,0 +1,177 @@
import { useRef, useState } from "react"; // use refs for reading value
import classess from "./InputData.module.css";
import Card from "../ui/Card";
import { ToastContainer ,toast , Zoom , Bounce } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css';
import Backdrop from '@mui/material/Backdrop';
import CircularProgress from '@mui/material/CircularProgress';
import Swal from 'sweetalert2'
import withReactContent from 'sweetalert2-react-content'
const MySwal = withReactContent(Swal)
function InputData(props) {
let datanya = props.data;
// console.log(datanya);
const usiaInputRef = useRef();
const beratInputRef = useRef();
const kelilingInputRef = useRef();
const ukuranBatangInputRef = useRef();
const jarakDuriInputRef = useRef();
const [loading, setLoading] = useState(false);
async function submitHandler(event) {
event.preventDefault(); // ini untuk prevent reload atau submit default
const usia = usiaInputRef.current.value;
const berat = beratInputRef.current.value;
const keliling = kelilingInputRef.current.value;
const ukuran_batang = ukuranBatangInputRef.current.value;
const jarak_duri = jarakDuriInputRef.current.value;
if(usia < datanya.detail_attribute.usia.min || usia > datanya.detail_attribute.usia.max-1){
toast.warning("Usia harus diantara "+datanya.detail_attribute.usia.min+" - "+`${datanya.detail_attribute.usia.max-1}`)
//focus back to input id=usia
usiaInputRef.current.focus();
}else if(berat < datanya.detail_attribute.berat.min || berat > datanya.detail_attribute.berat.max-50){
toast.warning("Berat harus diantara "+datanya.detail_attribute.berat.min+" - "+`${datanya.detail_attribute.berat.max-50}`)
//focus back to input id=berat
beratInputRef.current.focus();
}else if(keliling < datanya.detail_attribute.keliling.min || keliling > datanya.detail_attribute.keliling.max-1){
toast.warning("Keliling harus diantara "+datanya.detail_attribute.keliling.min+" - "+`${datanya.detail_attribute.keliling.max-1}`)
//focus back to input id=keliling
kelilingInputRef.current.focus();
}else if(ukuran_batang < datanya.detail_attribute.ukuran_batang.min || ukuran_batang > datanya.detail_attribute.ukuran_batang.max-0.5){
toast.warning("Ukuran batang harus diantara "+datanya.detail_attribute.ukuran_batang.min+" - "+`${datanya.detail_attribute.ukuran_batang.max-0.5}`)
//focus back to input id=ukuran_batang
ukuranBatangInputRef.current.focus();
}else if(jarak_duri < datanya.detail_attribute.jarak_duri.min || jarak_duri > datanya.detail_attribute.jarak_duri.max-0.5){
toast.warning("Jarak duri harus diantara "+datanya.detail_attribute.jarak_duri.min+" - "+`${datanya.detail_attribute.jarak_duri.max-0.5}`)
//focus back to input id=jarak_duri
jarakDuriInputRef.current.focus();
}
else{
const datanya = {
usia: usia,
berat: berat,
keliling: keliling,
ukuran_batang: ukuran_batang,
jarak_duri: jarak_duri,
};
// console.log(datanya);
let formdata = new FormData();
formdata.append("data", JSON.stringify(datanya));
setLoading(true);
try {
//fetch api post
const response = await fetch("http://127.0.0.1:5000/", {
method: "POST",
body: formdata,
})
const responseData = await response.json();
if(response.status === 200){
console.log(responseData);
await MySwal.fire({
title: `<strong>${responseData.ket}</strong>`,
html: <i>Hasil yang diinput adalah <b>{responseData.ket}</b> </i>,
icon: 'success',
showConfirmButton: false,
})
}else{
// create swal with 2 button ok and load , if ok is click then console.log("ok") else if load is click then console.log("load")
await MySwal.fire({
title: <strong>Gagal</strong>,
html: <i>Server Bermasalah </i>,
icon: 'error',
showConfirmButton: true,
showDenyButton: true,
confirmButtonText: 'Reload Page',
}).then(async (result) => {
if (result.value) {
window.location.reload();
}
})
}
setLoading(false);
} catch (error) {
console.log(error);
setLoading(false);
await MySwal.fire({
title: <strong>Gagal</strong>,
html: <i>Server Bermasalah </i>,
icon: 'error',
showConfirmButton: true,
showDenyButton: true,
confirmButtonText: 'Reload Page',
}).then(async (result) => {
if (result.value) {
window.location.reload();
}
})
}
// props.onAddMeetup(meetupData)
}
}
// create function oninput only accept number and .
function onInput(event) {
const value = event.target.value;
const regex = /^[0-9.]+$/;
if (!regex.test(value)) {
event.target.value = value.slice(0, -1);
}
}
return (
<Card>
<ToastContainer draggable={false} transition={Zoom} autoClose={2000} />
<Backdrop open={loading}><CircularProgress color="inherit" /></Backdrop>
<form className={classess.form} onSubmit={submitHandler}>
<div className={classess.control}>
<label htmlFor="title">Usia <i>(Minggu)</i> </label>
<input type="text" required id="usia" ref={usiaInputRef} placeholder={(datanya.status == 'error') ? 'Gagal Loading Server...' : `min ${datanya.detail_attribute.usia.min} - ${datanya.detail_attribute.usia.max-1} max` } onInput={onInput} minLength="1" maxLength="4" />
</div>
<div className={classess.control}>
<label htmlFor="image">Berat <i>(Gram)</i> </label>
<input type="text" required id="berat" placeholder={(datanya.status == 'error') ? 'Gagal Loading Server...' : `min ${datanya.detail_attribute.berat.min} - ${datanya.detail_attribute.berat.max-50} max` } ref={beratInputRef} onInput={onInput} minLength="3" maxLength="5" />
</div>
<div className={classess.control}>
<label htmlFor="address">Keliling Buah <i>(cm)</i> </label>
<input type="text" required id="keliling" placeholder={(datanya.status == 'error') ? 'Gagal Loading Server...' : `min ${datanya.detail_attribute.keliling.min} - ${datanya.detail_attribute.keliling.max-1} max` } ref={kelilingInputRef} onInput={onInput} minLength="2" maxLength="4"/>
</div>
<div className={classess.control}>
<label htmlFor="description">Ukuran Batang <i>(cm)</i></label>
<input type="text" required id="ukuran_batang" placeholder={(datanya.status == 'error') ? 'Gagal Loading Server...' : `min ${datanya.detail_attribute.ukuran_batang.min} - ${datanya.detail_attribute.ukuran_batang.max-0.5} max` } ref={ukuranBatangInputRef} onInput={onInput} minLength="1" maxLength="3"/>
</div>
<div className={classess.control}>
<label htmlFor="description">Jarak Duri <i>(mm)</i></label>
<input type="text" required id="jarak_duri" placeholder={(datanya.status == 'error') ? 'Gagal Loading Server...' : `min ${datanya.detail_attribute.jarak_duri.min} - ${datanya.detail_attribute.jarak_duri.max-0.5} max` } ref={jarakDuriInputRef} onInput={onInput} minLength="1" maxLength="4"/>
</div>
<div className={classess.actions} >
<button>Cek Kematangan</button>
</div>
</form>
</Card>
);
}
export default InputData;

View File

@ -0,0 +1,87 @@
.form {
padding: 0.5rem;
}
.control {
margin-bottom: 0.5rem;
overflow-x: auto;
}
.control label {
display: block;
font-weight: bold;
margin-bottom: 0.5rem;
}
.control input,
.control textarea {
display: block;
font: inherit;
border-radius: 4px;
border: 1px solid #ccc;
padding: 0.25rem;
width: 100%;
}
.actions {
margin-top: 1rem;
text-align: center;
}
.actions button {
font: inherit;
cursor: pointer;
background-color: #77002e;
color: white;
padding: 0.5rem 1.5rem;
border: 1px solid #77002e;
border-radius: 4px;
font-weight: bold;
}
.actions button:hover,
.actions button:active {
background-color: #a50e48;
border-color: #a50e48;
}
.table {
border-collapse: collapse;
width: 100%;
}
.table1 {
border-collapse: collapse;
width: 100%;
}
.table th, .table td {
border: 0px solid #ccc;
padding: 0.5rem;
}
.table1 th, .table1 td {
border: none;
padding: 0.5rem;
}
.table tr:nth-child(even) {
background-color: #d3d3d3;
}
.table tr:hover {
background-color: #eaeaea;
}
/* style the .table header */
.table th {
background-color: #77002e;
color: white;
text-align: left;
}
.image {
width: 100%;
height: auto;
}

View File

@ -0,0 +1,46 @@
import classess from "./InputData.module.css";
import Card from "../ui/Card";
function Penulis(){
return(
<Card>
<form className={classess.form} >
<div className={classess.control}>
<table className={classess.table1}>
<tr>
<td> </td>
<td width="25%"> Nama </td>
<td> <i>:</i> </td>
<td> <b> Namanya</b> </td>
</tr>
<tr>
<td> </td>
<td> NIM </td>
<td> <i>:</i> </td>
<td> <b> Namanya</b> </td>
</tr>
<tr>
<td> </td>
<td> Pembimbing 1 </td>
<td> <i>:</i> </td>
<td> <b> Namanya</b> </td>
</tr>
<tr>
<td> </td>
<td> Pembimbing 2 </td>
<td> <i>:</i> </td>
<td> <b> Namanya</b> </td>
</tr>
<tr>
<td> </td>
<td> Judul </td>
<td> <i>:</i> </td>
<td> <b> Namanya</b> </td>
</tr>
</table>
</div>
</form>
</Card>
)
}
export default Penulis;

View File

@ -0,0 +1,13 @@
import classes from "./Layout.module.css";
import MainNavigation from "./MainNavigation";
function Layout(props) {
return (
<div>
<MainNavigation />
<main className={classes.main}>{props.children}</main>
</div>
);
}
export default Layout;

View File

@ -0,0 +1,5 @@
.main {
margin: 3rem auto;
width: 90%;
max-width: 40rem;
}

View File

@ -0,0 +1,20 @@
import Link from "next/link";
import classess from './MainNavigation.module.css'
function MainNavigation() {
return (
<header className={classess.header}>
<div className={classess.logo}>Fuzzy Durian</div>
<nav className={classess.nav}>
<ul>
<li><Link href='/'>Cek Data</Link></li>
<li><Link href='/dataset'>Dataset</Link></li>
<li><Link href='/penulis'>Penulis</Link></li>
</ul>
</nav>
</header>
);
}
export default MainNavigation;

View File

@ -0,0 +1,61 @@
.header {
width: 100%;
height: 5rem;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #77002e;
padding: 0 10%;
}
.logo {
font-size: 2rem;
color: white;
font-weight: bold;
}
.header ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
align-items: baseline;
}
.header li {
margin-left: 3rem;
}
.header a {
text-decoration: none;
font-size: 1.5rem;
color: #fcb8d2;
}
.header a:hover,
.header a:active,
.header a.active {
color: white;
}
.badge {
background-color: #cc2062;
color: white;
border-radius: 12px;
padding: 0 1rem;
margin-left: 0.5rem;
}
/* if display < 600px then hide logo */
@media screen and (max-width: 600px) {
.header .logo {
display: none;
}
/* set the li from left to right */
.header li {
margin-left: 0;
/* add space between li */
margin-right: 1rem;
}
}

View File

@ -0,0 +1,9 @@
import classes from "./Card.module.css";
function Card(props) {
return <div className={classes.card}>
{props.children}
</div>
}
export default Card;

View File

@ -0,0 +1,5 @@
.card {
background-color: white;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

6
frontend/next.config.js Normal file
View File

@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig

6761
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
frontend/package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/material": "^5.5.3",
"next": "12.1.4",
"nextjs-progressbar": "^0.0.14",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-toastify": "^8.2.0",
"sweetalert2": "^11.4.8",
"sweetalert2-react-content": "^4.2.0"
},
"devDependencies": {
"eslint": "8.12.0",
"eslint-config-next": "12.1.4"
}
}

15
frontend/pages/_app.js Normal file
View File

@ -0,0 +1,15 @@
import Layout from '../components/layout/Layout'
import '../styles/globals.css'
import NextNProgress from "nextjs-progressbar";
function MyApp({ Component, pageProps }) {
return (
<>
<NextNProgress />
<Layout><Component {...pageProps} /></Layout>
</>
);
}
export default MyApp

View File

@ -0,0 +1,41 @@
import DataSet from "../../components/halaman/DataSet";
import Card from "../../components/ui/Card";
function PageDataSet(props){
let data = JSON.parse(props.data);
// console.log(data)
let status = JSON.parse(props.data).status;
// console.log(status)
return (status == "success") ?<DataSet data={data} /> : <Card> <br /> <center> <h2>Server Bermasalah ...</h2></center> <br /></Card>
// return <h1>okok</h1>
}
export async function getStaticProps() { // this code never end up on client side ,excecuted during build time
// fetch data from an API, for example
let data;
try {
//fetches data http://127.0.0.1:5000/ with method get
const response = await fetch('http://127.0.0.1:5000/', {
method: 'GET',
})
//convert response to json
data = await response.json()
data['status'] = 'success'
} catch (e) {
data = {"error": e,'status':'error'}
}
// console.log(data)
return {
props: { //this has to be named `props`
data: JSON.stringify(data)
},
revalidate: 10 //revalidate after 10 second
}
}
export default PageDataSet;

34
frontend/pages/index.js Normal file
View File

@ -0,0 +1,34 @@
import InputData from "../components/halaman/InputData";
function HomePage(props) {
const data = JSON.parse(props.data);
return <InputData data={data} />;
}
export async function getStaticProps() { // this code never end up on client side ,excecuted during build time
// fetch data from an API, for example
let data;
try {
//fetches data http://127.0.0.1:5000/ with method get
const response = await fetch('http://127.0.0.1:5000/', {
method: 'GET',
})
//convert response to json
data = await response.json()
data['status'] = 'success'
} catch (e) {
data = {"error": e,'status':'error'}
}
// console.log(data)
return {
props: { //this has to be named `props`
data: JSON.stringify(data)
},
revalidate: 10 //revalidate after 10 second
}
}
export default HomePage;

View File

@ -0,0 +1,7 @@
import Penulis from "../components/halaman/Penulis";
function penulisPage(){
return <Penulis />
}
export default penulisPage;

BIN
frontend/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,4 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,16 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}

2273
frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff