Compare commits
7 Commits
fix_fuzzy_
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
52649a0beb | ||
|
41305d18cd | ||
|
370df82259 | ||
|
9f8d758b6e | ||
|
b3964b3a97 | ||
|
7cff7f310a | ||
f75f3fded1 |
@ -50,7 +50,7 @@ INSTALLED_APPS = [
|
||||
"corsheaders",
|
||||
"django_filters",
|
||||
# apps
|
||||
'cars'
|
||||
"cars",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@ -156,3 +156,29 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
# CORS
|
||||
CORS_ALLOW_ALL_ORIGINS = True
|
||||
|
||||
PRODUCTION_YEAR = {
|
||||
"low": [1960, 1960, 2001],
|
||||
"mid": [1960, 2001, 2022],
|
||||
"high": [2017, 2022, 2022],
|
||||
}
|
||||
|
||||
MILEAGE = {
|
||||
"low": [0, 0, 50000],
|
||||
"mid": [0, 300000, 500000],
|
||||
"high": [300000, 500000, 500000],
|
||||
}
|
||||
|
||||
ENGINE_CAPACITY = {
|
||||
"low": [0.7, 0.7, 1.2],
|
||||
"mid": [1.2, 2.0, 8.2],
|
||||
"high": [5.0, 8.2, 8.2],
|
||||
}
|
||||
|
||||
COMBUSTION = {
|
||||
"low": [4.0, 4.0, 6.0],
|
||||
"mid": [4.0, 8.0, 15.0],
|
||||
"high": [8.5, 15.0, 15.0],
|
||||
}
|
||||
|
||||
COMPARATOR = 0.75
|
||||
|
@ -14,9 +14,6 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include('cars.urls'))
|
||||
]
|
||||
urlpatterns = [path("admin/", admin.site.urls), path("", include("cars.urls"))]
|
||||
|
@ -1,4 +1,5 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Car
|
||||
|
||||
admin.site.register(Car)
|
||||
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class CarsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'cars'
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "cars"
|
||||
|
@ -1,48 +1,83 @@
|
||||
import numpy as np
|
||||
import skfuzzy as fuzz
|
||||
from django.conf import settings
|
||||
from skfuzzy import control as ctrl
|
||||
|
||||
|
||||
def get_fuzzy_response(request_params, objects_list):
|
||||
|
||||
# Stworzenie uniwersum
|
||||
production_year = ctrl.Antecedent(np.arange(1960, 2022, 1), 'production_year')
|
||||
mileage = ctrl.Antecedent(np.arange(0, 500000, 1), 'mileage')
|
||||
engine_capacity = ctrl.Antecedent(np.arange(0.7, 8.2, 0.1), 'engine_capacity')
|
||||
combustion = ctrl.Antecedent(np.arange(4.0, 15.0, 0.1), 'combustion')
|
||||
production_year = ctrl.Antecedent(np.arange(1960, 2022, 1), "production_year")
|
||||
mileage = ctrl.Antecedent(np.arange(0, 500000, 1), "mileage")
|
||||
engine_capacity = ctrl.Antecedent(np.arange(0.7, 8.2, 0.1), "engine_capacity")
|
||||
combustion = ctrl.Antecedent(np.arange(4.0, 15.0, 0.1), "combustion")
|
||||
|
||||
# Tworzenie funkcji rozmytych
|
||||
production_year['low'] = fuzz.trimf(production_year.universe, [1960, 1960, 2001])
|
||||
production_year['mid'] = fuzz.trimf(production_year.universe, [1960, 2001, 2022])
|
||||
production_year['high'] = fuzz.trimf(production_year.universe, [2017, 2022, 2022])
|
||||
production_year["low"] = fuzz.trimf(
|
||||
production_year.universe, settings.PRODUCTION_YEAR["low"]
|
||||
)
|
||||
production_year["mid"] = fuzz.trimf(
|
||||
production_year.universe, settings.PRODUCTION_YEAR["mid"]
|
||||
)
|
||||
production_year["high"] = fuzz.trimf(
|
||||
production_year.universe, settings.PRODUCTION_YEAR["high"]
|
||||
)
|
||||
|
||||
mileage['low'] = fuzz.trimf(mileage.universe, [0, 0, 50000])
|
||||
mileage['mid'] = fuzz.trimf(mileage.universe, [0, 300000, 500000])
|
||||
mileage['high'] = fuzz.trimf(mileage.universe, [300000, 500000, 500000])
|
||||
mileage["low"] = fuzz.trimf(mileage.universe, settings.MILEAGE["low"])
|
||||
mileage["mid"] = fuzz.trimf(mileage.universe, settings.MILEAGE["mid"])
|
||||
mileage["high"] = fuzz.trimf(mileage.universe, settings.MILEAGE["high"])
|
||||
|
||||
engine_capacity['low'] = fuzz.trimf(engine_capacity.universe, [0.7, 0.7, 1.2])
|
||||
engine_capacity['mid'] = fuzz.trimf(engine_capacity.universe, [1.2, 2.0, 8.2])
|
||||
engine_capacity['high'] = fuzz.trimf(engine_capacity.universe, [5.0, 8.2, 8.2])
|
||||
engine_capacity["low"] = fuzz.trimf(
|
||||
engine_capacity.universe, settings.ENGINE_CAPACITY["low"]
|
||||
)
|
||||
engine_capacity["mid"] = fuzz.trimf(
|
||||
engine_capacity.universe, settings.ENGINE_CAPACITY["mid"]
|
||||
)
|
||||
engine_capacity["high"] = fuzz.trimf(
|
||||
engine_capacity.universe, settings.ENGINE_CAPACITY["high"]
|
||||
)
|
||||
|
||||
combustion["low"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["low"])
|
||||
combustion["mid"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["mid"])
|
||||
combustion["high"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["high"])
|
||||
|
||||
combustion['low'] = fuzz.trimf(combustion.universe, [4.0, 4.0, 6.0])
|
||||
combustion['mid'] = fuzz.trimf(combustion.universe, [4.0, 8.0, 15.0])
|
||||
combustion['high'] = fuzz.trimf(combustion.universe, [8.5, 15.0, 15.0])
|
||||
|
||||
# Obliczanie przynaleznosci danego obiektu do podanych danych kwerendy i tworzenie przefiltrowanej listy
|
||||
end_object_list = []
|
||||
for car in objects_list:
|
||||
comparator = []
|
||||
if 'production_year' in request_params:
|
||||
comparator.append(fuzz.interp_membership(production_year.universe, production_year[str(request_params['production_year'])].mf, car.production_year))
|
||||
if 'mileage' in request_params:
|
||||
comparator.append(fuzz.interp_membership(mileage.universe, mileage[str(request_params['mileage'])].mf, car.mileage))
|
||||
if 'engine_capacity' in request_params:
|
||||
comparator.append(fuzz.interp_membership(engine_capacity.universe, engine_capacity[str(request_params['engine_capacity'])].mf, car.engine_capacity))
|
||||
if 'combustion' in request_params:
|
||||
comparator.append(fuzz.interp_membership(combustion.universe, combustion[str(request_params['combustion'])].mf, car.combustion))
|
||||
if min(comparator) > 0.75:
|
||||
if "production_year" in request_params:
|
||||
comparator.append(
|
||||
fuzz.interp_membership(
|
||||
production_year.universe,
|
||||
production_year[str(request_params["production_year"])].mf,
|
||||
car.production_year,
|
||||
)
|
||||
)
|
||||
if "mileage" in request_params:
|
||||
comparator.append(
|
||||
fuzz.interp_membership(
|
||||
mileage.universe,
|
||||
mileage[str(request_params["mileage"])].mf,
|
||||
car.mileage,
|
||||
)
|
||||
)
|
||||
if "engine_capacity" in request_params:
|
||||
comparator.append(
|
||||
fuzz.interp_membership(
|
||||
engine_capacity.universe,
|
||||
engine_capacity[str(request_params["engine_capacity"])].mf,
|
||||
car.engine_capacity,
|
||||
)
|
||||
)
|
||||
if "combustion" in request_params:
|
||||
comparator.append(
|
||||
fuzz.interp_membership(
|
||||
combustion.universe,
|
||||
combustion[str(request_params["combustion"])].mf,
|
||||
car.combustion,
|
||||
)
|
||||
)
|
||||
if comparator and min(comparator) > settings.COMPARATOR:
|
||||
end_object_list.append(car)
|
||||
|
||||
return end_object_list
|
||||
|
||||
|
||||
return end_object_list
|
||||
|
@ -1,5 +1,6 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Car(models.Model):
|
||||
mark = models.CharField(max_length=150)
|
||||
model = models.CharField(max_length=150)
|
||||
@ -10,4 +11,4 @@ class Car(models.Model):
|
||||
price = models.DecimalField(decimal_places=2, max_digits=16)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "Car"
|
||||
return "Car"
|
||||
|
@ -1,15 +1,17 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Car
|
||||
|
||||
|
||||
class CarSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
class Meta:
|
||||
model = Car
|
||||
fields = [
|
||||
'mark',
|
||||
'model',
|
||||
'mileage',
|
||||
'production_year',
|
||||
'engine_capacity',
|
||||
'combustion',
|
||||
'price'
|
||||
]
|
||||
"mark",
|
||||
"model",
|
||||
"mileage",
|
||||
"production_year",
|
||||
"engine_capacity",
|
||||
"combustion",
|
||||
"price",
|
||||
]
|
||||
|
@ -1,7 +1,9 @@
|
||||
from django.urls import path, include
|
||||
from .views import CarList
|
||||
from django.urls import include, path
|
||||
|
||||
from .views import CarList, SettingsAPIView
|
||||
|
||||
# The API URLs are now determined automatically by the router.
|
||||
urlpatterns = [
|
||||
path('cars', CarList.as_view()),
|
||||
]
|
||||
path("cars", CarList.as_view()),
|
||||
path("settings", SettingsAPIView.as_view()),
|
||||
]
|
||||
|
@ -1,25 +1,49 @@
|
||||
VALUES = ['low', 'mid', 'high']
|
||||
from django.conf import settings
|
||||
|
||||
VALUES = ["low", "mid", "high"]
|
||||
|
||||
|
||||
def production_year_to_value(production_year):
|
||||
return VALUES[["Dawno", "Średnio", "Niedawno"].index(production_year)]
|
||||
|
||||
|
||||
def mileage_to_value(mileage):
|
||||
return VALUES[["Niski", "Średni", "Duży"].index(mileage)]
|
||||
|
||||
|
||||
def engine_capacity_to_value(engine_capacity):
|
||||
return VALUES[["Mała", "Średnia", "Ogromna"].index(engine_capacity)]
|
||||
|
||||
|
||||
def combustion_to_value(combustion):
|
||||
return VALUES[["Niskie", "Średnie", "Wysokie"].index(combustion)]
|
||||
|
||||
|
||||
def map_query_params(query_params):
|
||||
values = {}
|
||||
params = ['production_year', 'mileage', 'engine_capacity', 'combustion']
|
||||
funcs = [production_year_to_value, mileage_to_value, engine_capacity_to_value, combustion_to_value]
|
||||
params = ["production_year", "mileage", "engine_capacity", "combustion"]
|
||||
funcs = [
|
||||
production_year_to_value,
|
||||
mileage_to_value,
|
||||
engine_capacity_to_value,
|
||||
combustion_to_value,
|
||||
]
|
||||
for param, func in zip(params, funcs):
|
||||
if (query_param := query_params.get(param)):
|
||||
if query_param := query_params.get(param):
|
||||
values[param] = func(query_param)
|
||||
return values
|
||||
|
||||
|
||||
|
||||
def set_settings_values(data):
|
||||
settings.PRODUCTION_YEAR = get_values(data["production_year"])
|
||||
settings.MILEAGE = get_values(data["mileage"])
|
||||
settings.ENGINE_CAPACITY = get_values(data["engine_capacity"])
|
||||
settings.COMBUSTION = get_values(data["combustion"])
|
||||
settings.COMPARATOR = float(data["comparator"]["items"][0]["value"])
|
||||
|
||||
|
||||
def get_values(label):
|
||||
low = list(map(float, label["items"][0]["value"].split(",")))
|
||||
mid = list(map(float, label["items"][1]["value"].split(",")))
|
||||
high = list(map(float, label["items"][2]["value"].split(",")))
|
||||
return {"low": low, "mid": mid, "high": high}
|
||||
|
@ -1,16 +1,37 @@
|
||||
from django.conf import settings
|
||||
from rest_framework import generics
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .fuzzy_logic import get_fuzzy_response
|
||||
from .models import Car
|
||||
from .serializers import CarSerializer
|
||||
from .utils import map_query_params
|
||||
from .utils import map_query_params, set_settings_values
|
||||
|
||||
|
||||
class CarList(generics.ListAPIView):
|
||||
queryset = Car.objects.all()
|
||||
serializer_class = CarSerializer
|
||||
|
||||
|
||||
|
||||
def list(self, request):
|
||||
values = map_query_params(request.query_params)
|
||||
response = get_fuzzy_response(values, self.get_queryset())
|
||||
serializer = CarSerializer(response, many=True)
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class SettingsAPIView(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
set_settings_values(request.data)
|
||||
return Response("Settings changed")
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return Response(
|
||||
{
|
||||
"production_year": settings.PRODUCTION_YEAR,
|
||||
"mileage": settings.MILEAGE,
|
||||
"engine_capacity": settings.ENGINE_CAPACITY,
|
||||
"combustion": settings.COMBUSTION,
|
||||
"comparator": settings.COMPARATOR,
|
||||
}
|
||||
)
|
||||
|
@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<v-app-bar dense dark>
|
||||
<v-app-bar-nav-icon></v-app-bar-nav-icon>
|
||||
<v-app-bar-title>Systemy rozmyte</v-app-bar-title>
|
||||
<template v-slot:extension>
|
||||
<v-tabs align-with-title>
|
||||
<v-tab to="/">Strona główna</v-tab>
|
||||
<v-tab to="/settings">Ustawienia</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
</v-app-bar>
|
||||
</template>
|
||||
|
87
frontend/src/components/Settings.vue
Normal file
87
frontend/src/components/Settings.vue
Normal file
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row v-for="setting in settings" :key="setting.label">
|
||||
<v-col md="12">
|
||||
<h5>{{ setting.label }}</h5>
|
||||
</v-col>
|
||||
<v-col md="4" v-for="item in setting.items" :key="item.label">
|
||||
<v-text-field v-model="item.value" :label="item.label"> </v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-btn @click="changeSettings">Zmień ustawienia</v-btn>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
export default {
|
||||
name: "Table",
|
||||
|
||||
data: () => ({
|
||||
settings: {
|
||||
production_year: {
|
||||
label: "Rok produkcji",
|
||||
items: [
|
||||
{ label: "Dawno", value: "2000,2000,2009" },
|
||||
{ label: "Średnio", value: "2009,2012,2022" },
|
||||
{ label: "Niedawno", value: "2017,2022,2022" },
|
||||
],
|
||||
},
|
||||
mileage: {
|
||||
label: "Przebieg",
|
||||
items: [
|
||||
{ label: "Niski", value: "0,0,50000" },
|
||||
{ label: "Średni", value: "0,300000,500000" },
|
||||
{ label: "Duży", value: "300000,500000,500000" },
|
||||
],
|
||||
},
|
||||
engine_capacity: {
|
||||
label: "Pojemność silnika",
|
||||
items: [
|
||||
{ label: "Mała", value: "0.7,0.7,1.2" },
|
||||
{ label: "Średnia", value: "1.2,2.0,8.2" },
|
||||
{ label: "Ogromna", value: "5.0,8.2,8.2" },
|
||||
],
|
||||
},
|
||||
combustion: {
|
||||
label: "Spalanie paliwa",
|
||||
items: [
|
||||
{ label: "Niskie", value: "4.0,4.0,6.0" },
|
||||
{ label: "Średnie", value: "4.0,8.0,15.0" },
|
||||
{ label: "Wysokie", value: "8.5,15.0,15.0" },
|
||||
],
|
||||
},
|
||||
comparator: {
|
||||
label: "Stopień przynależności",
|
||||
items: [{ label: "", value: 0.75 }],
|
||||
},
|
||||
},
|
||||
}),
|
||||
computed: {},
|
||||
created() {
|
||||
this.getSettings();
|
||||
},
|
||||
methods: {
|
||||
changeSettings() {
|
||||
axios.post("http://localhost:8000/settings", this.settings);
|
||||
},
|
||||
setValuesToSettings(label, data) {
|
||||
this.settings[label].items[0].value = data[label].low.join(',')
|
||||
this.settings[label].items[1].value = data[label].mid.join(',')
|
||||
this.settings[label].items[2].value = data[label].high.join(',')
|
||||
},
|
||||
async getSettings() {
|
||||
const response = await axios.get("http://localhost:8000/settings");
|
||||
const data = response.data;
|
||||
this.settings.comparator.items[0].value = data.comparator
|
||||
this.setValuesToSettings('production_year', data)
|
||||
this.setValuesToSettings('mileage', data)
|
||||
this.setValuesToSettings('combustion', data)
|
||||
this.setValuesToSettings('engine_capacity', data)
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
@ -1,54 +1,58 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col md="12">
|
||||
<v-data-table :headers="headers" :items="getCars" class="elevation-1"></v-data-table>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col md="12">
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="getCars"
|
||||
class="elevation-1"
|
||||
></v-data-table>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
name: "Table",
|
||||
name: "Table",
|
||||
|
||||
data: () => ({
|
||||
headers: [
|
||||
{ text: "Marka", value: "brand" },
|
||||
{ text: "Model", value: "model" },
|
||||
{ text: "Przebieg (km)", value: "mileage" },
|
||||
{ text: "Rok produkcji", value: "production_year" },
|
||||
{ text: "Pojemnośc silnika (cm^3)", value: "engine_capacity" },
|
||||
{ text: "Spalanie (L/100km)", value: "combustion" },
|
||||
{ text: "Cena (zł)", value: "price" },
|
||||
],
|
||||
items: [{
|
||||
brand: "Ford",
|
||||
model: "Focus",
|
||||
mileage: 230000,
|
||||
production_year: 2008,
|
||||
engine_capacity: 2.0,
|
||||
combustion: 7.6,
|
||||
price: 12200,
|
||||
},
|
||||
{
|
||||
brand: "Fiat",
|
||||
model: "Punto",
|
||||
mileage: 430000,
|
||||
production_year: 2003,
|
||||
engine_capacity: 1.3,
|
||||
combustion: 5.5,
|
||||
price: 3500,
|
||||
},
|
||||
],
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['getCars'])
|
||||
}
|
||||
data: () => ({
|
||||
headers: [
|
||||
{ text: "Marka", value: "mark" },
|
||||
{ text: "Model", value: "model" },
|
||||
{ text: "Przebieg (km)", value: "mileage" },
|
||||
{ text: "Rok produkcji", value: "production_year" },
|
||||
{ text: "Pojemnośc silnika (cm^3)", value: "engine_capacity" },
|
||||
{ text: "Spalanie (L/100km)", value: "combustion" },
|
||||
{ text: "Cena (USD)", value: "price" },
|
||||
],
|
||||
items: [
|
||||
{
|
||||
brand: "Ford",
|
||||
model: "Focus",
|
||||
mileage: 230000,
|
||||
production_year: 2008,
|
||||
engine_capacity: 2.0,
|
||||
combustion: 7.6,
|
||||
price: 12200,
|
||||
},
|
||||
{
|
||||
brand: "Fiat",
|
||||
model: "Punto",
|
||||
mileage: 430000,
|
||||
production_year: 2003,
|
||||
engine_capacity: 1.3,
|
||||
combustion: 5.5,
|
||||
price: 3500,
|
||||
},
|
||||
],
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(["getCars"]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
@ -9,6 +9,11 @@ const routes = [
|
||||
name: "Home",
|
||||
component: () => import(/* webpackChunkName: "home" */ "../views/Home.vue"),
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
name: "Settings",
|
||||
component: () => import(/* webpackChunkName: "home" */ "../views/Settings.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
|
17
frontend/src/views/Settings.vue
Normal file
17
frontend/src/views/Settings.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<Settings class="my-5"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Settings from "../components/Settings";
|
||||
|
||||
export default {
|
||||
name: "Setting",
|
||||
|
||||
components: {
|
||||
Settings,
|
||||
},
|
||||
};
|
||||
</script>
|
7906
insert-data.sql
Normal file
7906
insert-data.sql
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user