Add settings page

This commit is contained in:
Bartosz Karwacki 2022-01-23 13:45:56 +01:00
parent f75f3fded1
commit 7cff7f310a
14 changed files with 256 additions and 60 deletions

View File

@ -50,7 +50,7 @@ INSTALLED_APPS = [
"corsheaders", "corsheaders",
"django_filters", "django_filters",
# apps # apps
'cars' "cars",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -156,3 +156,29 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# CORS # CORS
CORS_ALLOW_ALL_ORIGINS = True 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

View File

@ -16,7 +16,4 @@ Including another URLconf
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
urlpatterns = [ urlpatterns = [path("admin/", admin.site.urls), path("", include("cars.urls"))]
path("admin/", admin.site.urls),
path("", include('cars.urls'))
]

View File

@ -2,5 +2,5 @@ from django.apps import AppConfig
class CarsConfig(AppConfig): class CarsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = "django.db.models.BigAutoField"
name = 'cars' name = "cars"

View File

@ -1,48 +1,83 @@
import numpy as np import numpy as np
import skfuzzy as fuzz import skfuzzy as fuzz
from skfuzzy import control as ctrl from skfuzzy import control as ctrl
from django.conf import settings
def get_fuzzy_response(request_params, objects_list): def get_fuzzy_response(request_params, objects_list):
# Stworzenie uniwersum # Stworzenie uniwersum
production_year = ctrl.Antecedent(np.arange(1960, 2022, 1), 'production_year') production_year = ctrl.Antecedent(np.arange(1960, 2022, 1), "production_year")
mileage = ctrl.Antecedent(np.arange(0, 500000, 1), 'mileage') mileage = ctrl.Antecedent(np.arange(0, 500000, 1), "mileage")
engine_capacity = ctrl.Antecedent(np.arange(0.7, 8.2, 0.1), 'engine_capacity') 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') combustion = ctrl.Antecedent(np.arange(4.0, 15.0, 0.1), "combustion")
# Tworzenie funkcji rozmytych # Tworzenie funkcji rozmytych
production_year['low'] = fuzz.trimf(production_year.universe, [1960, 1960, 2001]) production_year["low"] = fuzz.trimf(
production_year['mid'] = fuzz.trimf(production_year.universe, [1960, 2001, 2022]) production_year.universe, settings.PRODUCTION_YEAR["low"]
production_year['high'] = fuzz.trimf(production_year.universe, [2017, 2022, 2022]) )
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["low"] = fuzz.trimf(mileage.universe, settings.MILEAGE["low"])
mileage['mid'] = fuzz.trimf(mileage.universe, [0, 300000, 500000]) mileage["mid"] = fuzz.trimf(mileage.universe, settings.MILEAGE["mid"])
mileage['high'] = fuzz.trimf(mileage.universe, [300000, 500000, 500000]) 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["low"] = fuzz.trimf(
engine_capacity['mid'] = fuzz.trimf(engine_capacity.universe, [1.2, 2.0, 8.2]) engine_capacity.universe, settings.ENGINE_CAPACITY["low"]
engine_capacity['high'] = fuzz.trimf(engine_capacity.universe, [5.0, 8.2, 8.2]) )
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, [4.0, 4.0, 6.0]) combustion["low"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["low"])
combustion['mid'] = fuzz.trimf(combustion.universe, [4.0, 8.0, 15.0]) combustion["mid"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["mid"])
combustion['high'] = fuzz.trimf(combustion.universe, [8.5, 15.0, 15.0]) combustion["high"] = fuzz.trimf(combustion.universe, settings.COMBUSTION["high"])
# Obliczanie przynaleznosci danego obiektu do podanych danych kwerendy i tworzenie przefiltrowanej listy # Obliczanie przynaleznosci danego obiektu do podanych danych kwerendy i tworzenie przefiltrowanej listy
end_object_list = [] end_object_list = []
for car in objects_list: for car in objects_list:
comparator = [] comparator = []
if 'production_year' in request_params: 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)) comparator.append(
if 'mileage' in request_params: fuzz.interp_membership(
comparator.append(fuzz.interp_membership(mileage.universe, mileage[str(request_params['mileage'])].mf, car.mileage)) production_year.universe,
if 'engine_capacity' in request_params: production_year[str(request_params["production_year"])].mf,
comparator.append(fuzz.interp_membership(engine_capacity.universe, engine_capacity[str(request_params['engine_capacity'])].mf, car.engine_capacity)) car.production_year,
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 "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) > settings.COMPARATOR:
end_object_list.append(car) end_object_list.append(car)
return end_object_list return end_object_list

View File

@ -1,5 +1,6 @@
from django.db import models from django.db import models
class Car(models.Model): class Car(models.Model):
mark = models.CharField(max_length=150) mark = models.CharField(max_length=150)
model = models.CharField(max_length=150) model = models.CharField(max_length=150)

View File

@ -1,15 +1,16 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Car from .models import Car
class CarSerializer(serializers.ModelSerializer): class CarSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Car model = Car
fields = [ fields = [
'mark', "mark",
'model', "model",
'mileage', "mileage",
'production_year', "production_year",
'engine_capacity', "engine_capacity",
'combustion', "combustion",
'price' "price",
] ]

View File

@ -1,7 +1,8 @@
from django.urls import path, include from django.urls import path, include
from .views import CarList from .views import CarList, SettingsAPIView
# The API URLs are now determined automatically by the router. # The API URLs are now determined automatically by the router.
urlpatterns = [ urlpatterns = [
path('cars', CarList.as_view()), path("cars", CarList.as_view()),
path("settings", SettingsAPIView.as_view()),
] ]

View File

@ -1,25 +1,49 @@
VALUES = ['low', 'mid', 'high'] from django.conf import settings
VALUES = ["low", "mid", "high"]
def production_year_to_value(production_year): def production_year_to_value(production_year):
return VALUES[["Dawno", "Średnio", "Niedawno"].index(production_year)] return VALUES[["Dawno", "Średnio", "Niedawno"].index(production_year)]
def mileage_to_value(mileage): def mileage_to_value(mileage):
return VALUES[["Niski", "Średni", "Duży"].index(mileage)] return VALUES[["Niski", "Średni", "Duży"].index(mileage)]
def engine_capacity_to_value(engine_capacity): def engine_capacity_to_value(engine_capacity):
return VALUES[["Mała", "Średnia", "Ogromna"].index(engine_capacity)] return VALUES[["Mała", "Średnia", "Ogromna"].index(engine_capacity)]
def combustion_to_value(combustion): def combustion_to_value(combustion):
return VALUES[["Niskie", "Średnie", "Wysokie"].index(combustion)] return VALUES[["Niskie", "Średnie", "Wysokie"].index(combustion)]
def map_query_params(query_params): def map_query_params(query_params):
values = {} values = {}
params = ['production_year', 'mileage', 'engine_capacity', 'combustion'] params = ["production_year", "mileage", "engine_capacity", "combustion"]
funcs = [production_year_to_value, mileage_to_value, engine_capacity_to_value, combustion_to_value] funcs = [
production_year_to_value,
mileage_to_value,
engine_capacity_to_value,
combustion_to_value,
]
for param, func in zip(params, funcs): 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) values[param] = func(query_param)
return values 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}

View File

@ -1,16 +1,25 @@
import re
from rest_framework import generics from rest_framework import generics
from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from .fuzzy_logic import get_fuzzy_response from .fuzzy_logic import get_fuzzy_response
from .models import Car from .models import Car
from .serializers import CarSerializer from .serializers import CarSerializer
from .utils import map_query_params from .utils import map_query_params, set_settings_values
class CarList(generics.ListAPIView): class CarList(generics.ListAPIView):
queryset = Car.objects.all() queryset = Car.objects.all()
serializer_class = CarSerializer serializer_class = CarSerializer
def list(self, request): def list(self, request):
values = map_query_params(request.query_params) values = map_query_params(request.query_params)
response = get_fuzzy_response(values, self.get_queryset()) response = get_fuzzy_response(values, self.get_queryset())
serializer = CarSerializer(response, many=True) 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")

View File

@ -1,6 +1,11 @@
<template> <template>
<v-app-bar dense dark> <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> <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> </v-app-bar>
</template> </template>

View File

@ -0,0 +1,75 @@
<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: "1960,1960,2001" },
{ label: "Średnio", value: "1960,2001,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: {
},
methods: {
changeSettings() {
axios.post('http://localhost:8000/settings', this.settings)
}
}
};
</script>
<style scoped>
</style>

View File

@ -15,7 +15,7 @@ export default {
data: () => ({ data: () => ({
headers: [ headers: [
{ text: "Marka", value: "brand" }, { text: "Marka", value: "mark" },
{ text: "Model", value: "model" }, { text: "Model", value: "model" },
{ text: "Przebieg (km)", value: "mileage" }, { text: "Przebieg (km)", value: "mileage" },
{ text: "Rok produkcji", value: "production_year" }, { text: "Rok produkcji", value: "production_year" },

View File

@ -9,6 +9,11 @@ const routes = [
name: "Home", name: "Home",
component: () => import(/* webpackChunkName: "home" */ "../views/Home.vue"), component: () => import(/* webpackChunkName: "home" */ "../views/Home.vue"),
}, },
{
path: "/settings",
name: "Settings",
component: () => import(/* webpackChunkName: "home" */ "../views/Settings.vue"),
},
]; ];
const router = new VueRouter({ const router = new VueRouter({

View 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>