commit 5012a7e2b64b2f92fd2ad909f083948116b97b3c Author: KUB0570 Date: Sun Mar 9 15:23:18 2025 +0100 first commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Graphs.iml b/.idea/Graphs.iml new file mode 100644 index 0000000..e111816 --- /dev/null +++ b/.idea/Graphs.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..1f78eac --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/db.sqlite3 + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b4a065c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a10be2f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/ruff.xml b/.idea/ruff.xml new file mode 100644 index 0000000..dc7b5c1 --- /dev/null +++ b/.idea/ruff.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/Graphs/__init__.py b/Graphs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Graphs/__pycache__/__init__.cpython-310.pyc b/Graphs/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..df22f47 Binary files /dev/null and b/Graphs/__pycache__/__init__.cpython-310.pyc differ diff --git a/Graphs/__pycache__/settings.cpython-310.pyc b/Graphs/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000..c54b5b1 Binary files /dev/null and b/Graphs/__pycache__/settings.cpython-310.pyc differ diff --git a/Graphs/__pycache__/urls.cpython-310.pyc b/Graphs/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000..b12821a Binary files /dev/null and b/Graphs/__pycache__/urls.cpython-310.pyc differ diff --git a/Graphs/__pycache__/wsgi.cpython-310.pyc b/Graphs/__pycache__/wsgi.cpython-310.pyc new file mode 100644 index 0000000..84ba3e3 Binary files /dev/null and b/Graphs/__pycache__/wsgi.cpython-310.pyc differ diff --git a/Graphs/asgi.py b/Graphs/asgi.py new file mode 100644 index 0000000..8f3fea3 --- /dev/null +++ b/Graphs/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for Graphs project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Graphs.settings') + +application = get_asgi_application() diff --git a/Graphs/settings.py b/Graphs/settings.py new file mode 100644 index 0000000..1a64ef8 --- /dev/null +++ b/Graphs/settings.py @@ -0,0 +1,125 @@ +""" +Django settings for Graphs project. + +Generated by 'django-admin startproject' using Django 4.2.5. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-_d+6%0z5*@jzz-wkemhw-qe5$pa_jv)vq4&oc=(5$-n0#oosso' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'src.apps.SrcConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'Graphs.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR / 'templates'] + , + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'Graphs.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/Graphs/urls.py b/Graphs/urls.py new file mode 100644 index 0000000..20611a1 --- /dev/null +++ b/Graphs/urls.py @@ -0,0 +1,11 @@ +from django.contrib import admin +from django.urls import path + +from src.views import IndexView, TypeView, InfoView + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', IndexView.as_view(), name='index'), + path('/', TypeView.as_view(), name='type'), + path('//', InfoView.as_view(), name='info'), +] diff --git a/Graphs/wsgi.py b/Graphs/wsgi.py new file mode 100644 index 0000000..e0d79ef --- /dev/null +++ b/Graphs/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for Graphs project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Graphs.settings') + +application = get_wsgi_application() diff --git a/__pycache__/manage.cpython-310.pyc b/__pycache__/manage.cpython-310.pyc new file mode 100644 index 0000000..5d648ec Binary files /dev/null and b/__pycache__/manage.cpython-310.pyc differ diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000..6fb6375 Binary files /dev/null and b/db.sqlite3 differ diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..4b457d4 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Graphs.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..f83718b --- /dev/null +++ b/poetry.lock @@ -0,0 +1,144 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "asgiref" +version = "3.8.1" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.8" +files = [ + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "django" +version = "4.2.20" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Django-4.2.20-py3-none-any.whl", hash = "sha256:213381b6e4405f5c8703fffc29cd719efdf189dec60c67c04f76272b3dc845b9"}, + {file = "Django-4.2.20.tar.gz", hash = "sha256:92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"}, +] + +[package.dependencies] +asgiref = ">=3.6.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "networkx" +version = "3.4.2" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.10" +files = [ + {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, + {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, +] + +[package.extras] +default = ["matplotlib (>=3.7)", "numpy (>=1.24)", "pandas (>=2.0)", "scipy (>=1.10,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.15)", "sphinx (>=7.3)", "sphinx-gallery (>=0.16)", "texext (>=0.6.7)"] +example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=1.9)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] +extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "sqlparse" +version = "0.5.3" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.8" +files = [ + {file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"}, + {file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"}, +] + +[package.extras] +dev = ["build", "hatch"] +doc = ["sphinx"] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2025.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, + {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "cf0c35bc75496d42ca7e5bae99bc0636ca80a3235326d52974de95a1169f310c" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4bfbb2a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "graphs" +version = "0.1.0" +description = "" +authors = ["KUB0570 "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.10" +django = "^4.2.5" +numpy = "^1.26.3" +networkx = "^3.2.1" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/__pycache__/__init__.cpython-310.pyc b/src/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..e125962 Binary files /dev/null and b/src/__pycache__/__init__.cpython-310.pyc differ diff --git a/src/__pycache__/admin.cpython-310.pyc b/src/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000..7cd25c2 Binary files /dev/null and b/src/__pycache__/admin.cpython-310.pyc differ diff --git a/src/__pycache__/apps.cpython-310.pyc b/src/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000..2a8714b Binary files /dev/null and b/src/__pycache__/apps.cpython-310.pyc differ diff --git a/src/__pycache__/models.cpython-310.pyc b/src/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000..f7cd2ef Binary files /dev/null and b/src/__pycache__/models.cpython-310.pyc differ diff --git a/src/__pycache__/views.cpython-310.pyc b/src/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000..6d08935 Binary files /dev/null and b/src/__pycache__/views.cpython-310.pyc differ diff --git a/src/admin.py b/src/admin.py new file mode 100644 index 0000000..f2a35b9 --- /dev/null +++ b/src/admin.py @@ -0,0 +1,24 @@ +# from django.contrib import admin +# from src.models import Graph, Vertex, Arc +# +# +# @admin.register(Graph) +# class GraphAdmin(admin.ModelAdmin): +# list_display = [ +# "graph_type", +# "antimagic", +# "strong", +# "vertex", +# "arc" +# ] +# +# +# @admin.register(Vertex) +# class VertexAdmin(admin.ModelAdmin): +# list_display = ["graph", "in_weight", "out_weight", "label"] +# +# +# @admin.register(Arc) +# class ArcAdmin(admin.ModelAdmin): +# list_display = ["vertex_in", "vertex_out", "label"] +# diff --git a/src/apps.py b/src/apps.py new file mode 100644 index 0000000..ed8dc1a --- /dev/null +++ b/src/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class SrcConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'src' diff --git a/src/management/__init__.py b/src/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/management/__pycache__/__init__.cpython-310.pyc b/src/management/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..7653fde Binary files /dev/null and b/src/management/__pycache__/__init__.cpython-310.pyc differ diff --git a/src/management/commands/__init__.py b/src/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/management/commands/__pycache__/__init__.cpython-310.pyc b/src/management/commands/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..c6dad8e Binary files /dev/null and b/src/management/commands/__pycache__/__init__.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/core.cpython-310.pyc b/src/management/commands/__pycache__/core.cpython-310.pyc new file mode 100644 index 0000000..96f37ee Binary files /dev/null and b/src/management/commands/__pycache__/core.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/create_cycle.cpython-310.pyc b/src/management/commands/__pycache__/create_cycle.cpython-310.pyc new file mode 100644 index 0000000..28d56cb Binary files /dev/null and b/src/management/commands/__pycache__/create_cycle.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/create_graph.cpython-310.pyc b/src/management/commands/__pycache__/create_graph.cpython-310.pyc new file mode 100644 index 0000000..d247363 Binary files /dev/null and b/src/management/commands/__pycache__/create_graph.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/create_path.cpython-310.pyc b/src/management/commands/__pycache__/create_path.cpython-310.pyc new file mode 100644 index 0000000..fec8611 Binary files /dev/null and b/src/management/commands/__pycache__/create_path.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/create_tadpole.cpython-310.pyc b/src/management/commands/__pycache__/create_tadpole.cpython-310.pyc new file mode 100644 index 0000000..f4f3402 Binary files /dev/null and b/src/management/commands/__pycache__/create_tadpole.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/default.cpython-310.pyc b/src/management/commands/__pycache__/default.cpython-310.pyc new file mode 100644 index 0000000..393d73e Binary files /dev/null and b/src/management/commands/__pycache__/default.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/path.cpython-310.pyc b/src/management/commands/__pycache__/path.cpython-310.pyc new file mode 100644 index 0000000..9d6f1be Binary files /dev/null and b/src/management/commands/__pycache__/path.cpython-310.pyc differ diff --git a/src/management/commands/__pycache__/visualizate.cpython-310.pyc b/src/management/commands/__pycache__/visualizate.cpython-310.pyc new file mode 100644 index 0000000..527434e Binary files /dev/null and b/src/management/commands/__pycache__/visualizate.cpython-310.pyc differ diff --git a/src/management/commands/core.py b/src/management/commands/core.py new file mode 100644 index 0000000..813ca43 --- /dev/null +++ b/src/management/commands/core.py @@ -0,0 +1,21 @@ +from src.models import Arc + + +def create_arc(vertex_in, vertex_out, arc_num, label=None): + Arc.objects.create( + vertex_in=vertex_in, + vertex_out=vertex_out, + label=label + ) + return arc_num+1 + + +def get_arc(first, second, n, idx): + if Arc.objects.filter(vertex_out=first, vertex_in=second).exists(): + arc = Arc.objects.get(vertex_out=first, vertex_in=second) + else: + arc = Arc.objects.get(vertex_out=second, vertex_in=first) + first = second + arc.label = n + idx + arc.save() + return first diff --git a/src/management/commands/create_cycle.py b/src/management/commands/create_cycle.py new file mode 100644 index 0000000..6573d31 --- /dev/null +++ b/src/management/commands/create_cycle.py @@ -0,0 +1,116 @@ +from django.core.management.base import BaseCommand +from django.db import transaction + +from src.management.commands.default import delete_graphs +from src.management.commands.core import create_arc, get_arc +from src.models import Graph, Vertex, Arc +import time + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument('min', type=int) + parser.add_argument('max', type=int) + + def handle(self, *args, **options): + delete_graphs(Graph.CYCLE) + + min = options['min'] + max = options['max'] + + s_time = time.time() + for n in range(min, max + 1): + start_time = time.time() + self.create_cycle(n) + end_time = time.time() + elapsed_time = end_time - start_time + + print("Čas trvání", n, "vrcholů:", elapsed_time, "sekund") + + e_time = time.time() + eed_time = e_time - s_time + + print("Celkový čas trvání:", eed_time, "sekund") + + def create_cycle(self, n): + with transaction.atomic(): + for i in range(2 ** n): + binary_number = bin(i)[2:].zfill(n) + if binary_number[:2] not in ['01', '10']: + continue + graph = self.create_graph(binary_number) + vertex = None + vertices = Vertex.objects.filter(graph=graph) + vertices_list = [] + + for num, v in enumerate(vertices): + vertices_list.append(v) + if v.max_degree == 2 and not vertex: + vertex = v + + right = vertices_list.index(vertex) + left = vertices_list.index(vertex)-1 + section = True + + right_ark = vertices_list[right % n] + left_ark = vertices_list[right % n] + for idx in range(n): + location = (right % n) if section else left + now = vertices_list[location] + now.index = idx + 1 + now.save() + if section: + if right_ark != now: + right_ark = get_arc(first=right_ark, second=now, n=n, idx=idx) + right += 1 + else: + left_ark = get_arc(first=left_ark, second=now, n=n, idx=idx) + left -= 1 + + if now.max_degree == 2: + section = not section + + if Arc.objects.filter(vertex_out=right_ark, vertex_in=left_ark).exists(): + arc = Arc.objects.get(vertex_out=right_ark, vertex_in=left_ark) + else: + arc = Arc.objects.get(vertex_out=left_ark, vertex_in=right_ark) + arc.label = n + n + arc.save() + + sorted_vertices = sorted(vertices_list, key=lambda vertex: (vertex.max_degree, vertex.index)) + for num, v in enumerate(sorted_vertices): + v.label = num + 1 + v.save() + + graph.update() + + @staticmethod + def create_graph(binary_number): + prev_vertex = None + first_vertex = None + first_bit = None + arc_num = 1 + graph = Graph.objects.create( + graph_type=Graph.CYCLE, + binary=binary_number, + ) + + for j, bit in enumerate(binary_number): + vertex = Vertex.objects.create(graph=graph, label=j + 1) + if prev_vertex: + arc_num = create_arc( + vertex_in=prev_vertex if bit == '0' else vertex, + vertex_out=vertex if bit == '0' else prev_vertex, + arc_num=arc_num + ) + else: + first_vertex = vertex + first_bit = bit + prev_vertex = vertex + create_arc( + vertex_in=prev_vertex if first_bit == '0' else first_vertex, + vertex_out=first_vertex if first_bit == '0' else prev_vertex, + arc_num=arc_num + ) + return graph + diff --git a/src/management/commands/create_graph.py b/src/management/commands/create_graph.py new file mode 100644 index 0000000..91b935a --- /dev/null +++ b/src/management/commands/create_graph.py @@ -0,0 +1,31 @@ +from django.core.management.base import BaseCommand + +from src.management.commands.default import ( + delete_graphs, + GRAPHS +) + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument('graph', nargs='+', type=str) + parser.add_argument('--min', type=int, default=3) + parser.add_argument('--max', type=int, default=5) + + def handle(self, *args, **options): + delete_graphs("all") + graphs = options['graph'] + min = options['min'] + max = options['max'] + + component = None + for graph in graphs: + component = GRAPHS[graph](component) + + for n in range(min, max + 1): + for i in range(2 ** (n - 1)): + binary_number = bin(i)[2:].zfill(n) + + if i >= 2 ** (n - 1) / 2 - 1: + break + diff --git a/src/management/commands/create_path.py b/src/management/commands/create_path.py new file mode 100644 index 0000000..89dcb1f --- /dev/null +++ b/src/management/commands/create_path.py @@ -0,0 +1,108 @@ +from django.core.management.base import BaseCommand +from django.db import transaction +from django.db.models import Count, Max, F, OuterRef, Subquery, ExpressionWrapper, IntegerField +from django.db.models.functions import Coalesce + +from src.management.commands.default import delete_graphs +from src.management.commands.core import create_arc +from src.models import Graph, Vertex, Arc +import time + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument('min', type=int) + parser.add_argument('max', type=int) + + def handle(self, *args, **options): + delete_graphs("all") + + min = options['min'] + max = options['max'] + + s_time = time.time() + for n in range(min, max + 1): + start_time = time.time() + self.create_path(n) + end_time = time.time() + elapsed_time = end_time - start_time + + print("Čas trvání", n, "vrcholů:", elapsed_time, "sekund") + e_time = time.time() + eed_time = e_time - s_time + + print("Celkový čas trvání:", eed_time, "sekund") + + def create_path(self, n): + with transaction.atomic(): + for i in range(2 ** (n-1)): + binary_number = bin(i)[2:].zfill(n) + graph = self.create_graph(n, binary_number) + + arc_count_in_subquery = ( + Arc.objects + .filter(vertex_in=OuterRef('pk')) + .values('vertex_in') + .annotate(arc_count_in=Count('label')) + .values('arc_count_in') + .order_by('-arc_count_in') + [:1] + ) + + arc_count_out_subquery = ( + Arc.objects + .filter(vertex_out=OuterRef('pk')) + .values('vertex_out') + .annotate(arc_count_out=Count('label')) + .values('arc_count_out') + .order_by('-arc_count_out') + [:1] + ) + + # Získání maximálního počtu arků pro každý vrchol + vertices = ( + Vertex.objects + .filter(graph=graph) + .annotate(arc_count_in=Coalesce(Subquery(arc_count_in_subquery, output_field=IntegerField()), 0)) + .annotate(arc_count_out=Coalesce(Subquery(arc_count_out_subquery, output_field=IntegerField()), 0)) + .annotate(max_arc_count=ExpressionWrapper( + Max(F('arc_count_in'), F('arc_count_out')), + output_field=IntegerField() + )) + .order_by('max_arc_count', 'label') + ) + for num, v in enumerate(vertices): + v.label = num + 1 + v.save() + graph.update() + + if i >= 2 ** (n - 1) / 2 - 1: + break + + @staticmethod + def create_graph(n, binary_number): + prev_vertex = None + arc_num = 0 + graph = Graph.objects.create( + graph_type=Graph.PATH, + binary=binary_number[1:], + ) + + for j, bit in enumerate(binary_number): + vertex = Vertex.objects.create(graph=graph, index=j + 1) + if prev_vertex: + arc_num = create_arc( + vertex_in=prev_vertex if bit == '0' else vertex, + vertex_out=vertex if bit == '0' else prev_vertex, + arc_num=arc_num, + label=n + arc_num + ) + prev_vertex = vertex + return graph + + + # for i in range(2 ** (n - 1)): + # binary_number = bin(i)[2:].zfill(n) + # + # if i >= 2 ** (n - 1) / 2 - 1: + # break \ No newline at end of file diff --git a/src/management/commands/create_tadpole.py b/src/management/commands/create_tadpole.py new file mode 100644 index 0000000..0ab0f46 --- /dev/null +++ b/src/management/commands/create_tadpole.py @@ -0,0 +1,97 @@ +from django.core.management.base import BaseCommand +from django.db import transaction + +from src.management.commands.default import delete_graphs, count_change +from src.management.commands.core import create_arc, get_arc +from src.models import Graph, Vertex, Arc + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument('min_n', type=int) + parser.add_argument('max_n', type=int) + parser.add_argument('min_m', type=int) + parser.add_argument('max_m', type=int) + + def handle(self, *args, **options): + delete_graphs("all") + + min_n = options['min_n'] + max_n = options['max_n'] + min_m = options['min_m'] + max_m = options['max_m'] + for n in range(min_n, max_n + 1): + for m in range(min_m, max_m + 1): + self.create_tadpole(n, m) + + def create_tadpole(self, n, m): + with transaction.atomic(): + for i in range(1, (2 ** n)): + for j in range(1, (2 ** m)): + binary_number_n = bin(i)[2:].zfill(n) + binary_number_m = bin(j)[2:].zfill(m) + + print(binary_number_n, binary_number_m) + graph = self.create_graph(binary_number_n, binary_number_m) + if graph: + graph.update() + + def create_graph(self, binary_number_n, binary_number_m): + length = len(binary_number_n+binary_number_m) + graph = Graph.objects.create( + graph_type=Graph.TADPOLE, + binary=binary_number_n + binary_number_m, + ) + + a = count_change(binary_number_n+binary_number_n[0]) + count_change(binary_number_m) + if binary_number_n[0] == binary_number_m[0] and binary_number_n[-1] != binary_number_m[0]: + return self.max_degree_3(binary_number_n, binary_number_m, graph, length, a) + else: + return self.max_degree_2() + + @staticmethod + def max_degree_3(binary_number_n, binary_number_m, graph, length, a): + arc_num = 1 + labeling = [i for i in range(1, length + 1)] + label = length - a + 1 + labeling.remove(label) + prev_vertex = vertex3 = Vertex.objects.create(graph=graph, label=label) + for j, bit in enumerate(binary_number_n): + vertex = vertex3 if j == len(binary_number_n) - 1 else Vertex.objects.create(graph=graph) + arc_num = create_arc( + vertex_in=prev_vertex if bit == '0' else vertex, + vertex_out=vertex if bit == '0' else prev_vertex, + arc_num=arc_num, + label=arc_num + length + ) + prev_vertex = vertex + + prev_vertex = vertex3 + for j, bit in enumerate(binary_number_m): + vertex = Vertex.objects.create(graph=graph) + arc_num = create_arc( + vertex_in=prev_vertex if bit == '0' else vertex, + vertex_out=vertex if bit == '0' else prev_vertex, + arc_num=arc_num, + label=arc_num + length + ) + prev_vertex = vertex + + vertices = Vertex.objects.filter(graph=graph) + for vertex in vertices: + if vertex.max_degree == 2: + label = min([x for x in labeling if x > (length - a + 1)]) + labeling.remove(label) + vertex.label = label + vertex.save() + if vertex.max_degree == 1: + label = min([x for x in labeling if x < (length - a + 1)]) + labeling.remove(label) + vertex.label = label + vertex.save() + return graph + + @staticmethod + def max_degree_2(): + return None + diff --git a/src/management/commands/default.py b/src/management/commands/default.py new file mode 100644 index 0000000..7f2998a --- /dev/null +++ b/src/management/commands/default.py @@ -0,0 +1,55 @@ +from src.management.commands.path import path +from src.models import Graph, Vertex, Arc + + +def delete_graphs(type_of_graph): + if type_of_graph == "all": + Graph.objects.all().delete() + Vertex.objects.all().delete() + Arc.objects.all().delete() + else: + Graph.objects.filter(graph_type=type_of_graph).delete() + Vertex.objects.filter(graph__graph_type=type_of_graph).delete() + Arc.objects.filter(vertex_in__graph__graph_type=type_of_graph).delete() + + +def count_change(binary_number): + change = 0 + actual_bit = binary_number[0] + + for bit in binary_number: + if bit != actual_bit: + change += 1 + actual_bit = bit + return change + + +def create_path(n, binary_number, graph=None): + if graph: + return path() + return print("new path") + + +def create_cycle(graph=None): + if graph: + return print("cycle") + return print("new cycle") + + +# def create_tadpole(graph=None): +# if graph: +# return print("tadpole") +# return print("new tadpole") + + +GRAPHS = { + Graph.CYCLE: create_cycle, + Graph.PATH: create_path, + # Graph.TADPOLE: create_tadpole, +} + + +# def unite_graph(function, graph=None): +# if graph: +# return function(graph) +# return function() diff --git a/src/management/commands/path.py b/src/management/commands/path.py new file mode 100644 index 0000000..717a15c --- /dev/null +++ b/src/management/commands/path.py @@ -0,0 +1,74 @@ +from django.db import transaction +from django.db.models import OuterRef, Count, Subquery, ExpressionWrapper, IntegerField, F, Max +from django.db.models.functions import Coalesce + +from src.management.commands.core import create_arc +from src.models import Arc, Vertex, Graph + + +def path(n, binary_number): + with transaction.atomic(): + graph = create_path(n, binary_number) + + arc_count_in_subquery = ( + Arc.objects + .filter(vertex_in=OuterRef('pk')) + .values('vertex_in') + .annotate(arc_count_in=Count('label')) + .values('arc_count_in') + .order_by('-arc_count_in') + [:1] + ) + + arc_count_out_subquery = ( + Arc.objects + .filter(vertex_out=OuterRef('pk')) + .values('vertex_out') + .annotate(arc_count_out=Count('label')) + .values('arc_count_out') + .order_by('-arc_count_out') + [:1] + ) + + # Získání maximálního počtu arků pro každý vrchol + vertices = ( + Vertex.objects + .filter(graph=graph) + .annotate(arc_count_in=Coalesce(Subquery(arc_count_in_subquery, output_field=IntegerField()), 0)) + .annotate(arc_count_out=Coalesce(Subquery(arc_count_out_subquery, output_field=IntegerField()), 0)) + .annotate(max_arc_count=ExpressionWrapper( + Max(F('arc_count_in'), F('arc_count_out')), + output_field=IntegerField() + )) + .order_by('max_arc_count', 'label') + ) + for num, v in enumerate(vertices): + v.label = num + 1 + v.save() + graph.update() + + +def create_path(n, binary_number, graph=None): + prev_vertex = None + arc_num = 0 + if graph: + graph.components += 1 + graph.graph_type = Graph.UNITED + graph.save() + else: + graph = Graph.objects.create( + graph_type=Graph.PATH, + binary=binary_number[1:], + ) + + for j, bit in enumerate(binary_number): + vertex = Vertex.objects.create(graph=graph, index=j + 1) + if prev_vertex: + arc_num = create_arc( + vertex_in=prev_vertex if bit == '0' else vertex, + vertex_out=vertex if bit == '0' else prev_vertex, + arc_num=arc_num, + label=n + arc_num + ) + prev_vertex = vertex + return graph \ No newline at end of file diff --git a/src/management/commands/visualizate.py b/src/management/commands/visualizate.py new file mode 100644 index 0000000..260e3af --- /dev/null +++ b/src/management/commands/visualizate.py @@ -0,0 +1,67 @@ +from django.core.management.base import BaseCommand + +import numpy as np +import networkx as nx +import matplotlib.pyplot as plt +from src.models import Graph, Vertex, Arc + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument('id', type=int) + # parser.add_argument('graph_type', type=str) + # parser.add_argument('binary', type=str) + + def handle(self, *args, **options): + id = options['id'] + # graph_type = options['graph_type'] + # binary = options['binary'] + + graph = Graph.objects.filter( + # graph_type=graph_type, binary=binary + id=id + ).first() + + if not graph: + return + + vertices = Vertex.objects.filter(graph=graph) + arcs = Arc.objects.filter(vertex_in__graph=graph) + + adjacency_matrix = np.zeros((len(vertices), len(vertices))) + + for arc in arcs: + adjacency_matrix[arc.vertex_in.index - 1][arc.vertex_out.index - 1] = 1 + adjacency_matrix[arc.vertex_out.index - 1][arc.vertex_in.index - 1] = 1 + + # Create a degree matrix + degree_matrix = np.diag(np.sum(adjacency_matrix, axis=1)) + + # Create Laplacian matrix + laplacian_matrix = degree_matrix - adjacency_matrix + + # Calculate eigenvalues and eigenvectors of the Laplacian matrix + eigenvalues, eigenvectors = np.linalg.eigh(laplacian_matrix) + + # Get the second smallest eigenvector (the smallest is constant) + second_smallest_eigenvector = eigenvectors[:, 1] + + # Use the eigenvector values as x, y coordinates for visualization + x_coordinates = second_smallest_eigenvector.real + y_coordinates = eigenvectors[:, 2].real # You can choose a different eigenvector if needed + + # Visualize the graph using matplotlib + plt.scatter(x_coordinates, y_coordinates, c='blue', s=100) + for i, vertex in enumerate(vertices): + plt.text(x_coordinates[i], y_coordinates[i], str(vertex.index)) + + # Draw lines between connected vertices + for arc in arcs: + index_in = arc.vertex_in.index - 1 + index_out = arc.vertex_out.index - 1 + plt.plot([x_coordinates[index_in], x_coordinates[index_out]], + [y_coordinates[index_in], y_coordinates[index_out]], + color='gray', linestyle='-', linewidth=1) + + plt.title('Graph Visualization with Edges using Laplacian Eigenmaps') + plt.show() \ No newline at end of file diff --git a/src/migrations/0001_initial.py b/src/migrations/0001_initial.py new file mode 100644 index 0000000..12305b4 --- /dev/null +++ b/src/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2.5 on 2024-01-29 16:19 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Graph', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('graph_type', models.CharField(choices=[('cycle', 'cycle'), ('path', 'path')], max_length=8)), + ('arcs', models.CharField(blank=True, max_length=128, null=True)), + ('arc_binary', models.IntegerField(blank=True, null=True)), + ('antimagic', models.BooleanField(default=False)), + ('super', models.BooleanField(default=False)), + ('strict', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Vertex', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('index', models.IntegerField(blank=True, default=0, null=True)), + ('label', models.IntegerField(blank=True, default=0, null=True)), + ('graph', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='vertices', to='src.graph')), + ], + ), + migrations.CreateModel( + name='Arc', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.IntegerField(blank=True, default=0, null=True)), + ('vertex_in', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='in_arcs', to='src.vertex')), + ('vertex_out', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='out_arcs', to='src.vertex')), + ], + ), + ] diff --git a/src/migrations/0002_alter_graph_arc_binary.py b/src/migrations/0002_alter_graph_arc_binary.py new file mode 100644 index 0000000..69d57ae --- /dev/null +++ b/src/migrations/0002_alter_graph_arc_binary.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-01-29 18:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('src', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='graph', + name='arc_binary', + field=models.CharField(blank=True, max_length=2048, null=True), + ), + ] diff --git a/src/migrations/0003_rename_arc_binary_graph_binary_remove_graph_arcs.py b/src/migrations/0003_rename_arc_binary_graph_binary_remove_graph_arcs.py new file mode 100644 index 0000000..e82dd36 --- /dev/null +++ b/src/migrations/0003_rename_arc_binary_graph_binary_remove_graph_arcs.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2024-01-29 18:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('src', '0002_alter_graph_arc_binary'), + ] + + operations = [ + migrations.RenameField( + model_name='graph', + old_name='arc_binary', + new_name='binary', + ), + migrations.RemoveField( + model_name='graph', + name='arcs', + ), + ] diff --git a/src/migrations/0004_graph_components.py b/src/migrations/0004_graph_components.py new file mode 100644 index 0000000..b106192 --- /dev/null +++ b/src/migrations/0004_graph_components.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-03-05 10:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('src', '0003_rename_arc_binary_graph_binary_remove_graph_arcs'), + ] + + operations = [ + migrations.AddField( + model_name='graph', + name='components', + field=models.IntegerField(default=1), + ), + ] diff --git a/src/migrations/0005_rename_strict_graph_strong_remove_graph_super_and_more.py b/src/migrations/0005_rename_strict_graph_strong_remove_graph_super_and_more.py new file mode 100644 index 0000000..cb99e0e --- /dev/null +++ b/src/migrations/0005_rename_strict_graph_strong_remove_graph_super_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.5 on 2024-04-25 07:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('src', '0004_graph_components'), + ] + + operations = [ + migrations.RenameField( + model_name='graph', + old_name='strict', + new_name='strong', + ), + migrations.RemoveField( + model_name='graph', + name='super', + ), + migrations.AlterField( + model_name='graph', + name='graph_type', + field=models.CharField(choices=[('cycle', 'cycle'), ('path', 'path'), ('tadpole', 'tadpole'), ('united', 'united')], max_length=8), + ), + ] diff --git a/src/migrations/__init__.py b/src/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/migrations/__pycache__/0001_initial.cpython-310.pyc b/src/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 0000000..baed700 Binary files /dev/null and b/src/migrations/__pycache__/0001_initial.cpython-310.pyc differ diff --git a/src/migrations/__pycache__/0002_alter_graph_arc_binary.cpython-310.pyc b/src/migrations/__pycache__/0002_alter_graph_arc_binary.cpython-310.pyc new file mode 100644 index 0000000..db1e5fc Binary files /dev/null and b/src/migrations/__pycache__/0002_alter_graph_arc_binary.cpython-310.pyc differ diff --git a/src/migrations/__pycache__/0003_rename_arc_binary_graph_binary_remove_graph_arcs.cpython-310.pyc b/src/migrations/__pycache__/0003_rename_arc_binary_graph_binary_remove_graph_arcs.cpython-310.pyc new file mode 100644 index 0000000..e4afdb4 Binary files /dev/null and b/src/migrations/__pycache__/0003_rename_arc_binary_graph_binary_remove_graph_arcs.cpython-310.pyc differ diff --git a/src/migrations/__pycache__/0004_graph_components.cpython-310.pyc b/src/migrations/__pycache__/0004_graph_components.cpython-310.pyc new file mode 100644 index 0000000..4865844 Binary files /dev/null and b/src/migrations/__pycache__/0004_graph_components.cpython-310.pyc differ diff --git a/src/migrations/__pycache__/0005_rename_strict_graph_strong_remove_graph_super_and_more.cpython-310.pyc b/src/migrations/__pycache__/0005_rename_strict_graph_strong_remove_graph_super_and_more.cpython-310.pyc new file mode 100644 index 0000000..898c3bd Binary files /dev/null and b/src/migrations/__pycache__/0005_rename_strict_graph_strong_remove_graph_super_and_more.cpython-310.pyc differ diff --git a/src/migrations/__pycache__/__init__.cpython-310.pyc b/src/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..b85f1d2 Binary files /dev/null and b/src/migrations/__pycache__/__init__.cpython-310.pyc differ diff --git a/src/models.py b/src/models.py new file mode 100644 index 0000000..2326ab4 --- /dev/null +++ b/src/models.py @@ -0,0 +1,100 @@ +from django.db import models + + +class Graph(models.Model): + CYCLE = "cycle" + PATH = "path" + TADPOLE = "tadpole" + UNITED = "united" + + GRAPHS = ( + (CYCLE, "cycle"), + (PATH, "path"), + (TADPOLE, "tadpole"), + (UNITED, "united") + ) + + graph_type = models.CharField(max_length=8, choices=GRAPHS) + binary = models.CharField(max_length=2048, blank=True, null=True) + components = models.IntegerField(default=1) + + antimagic = models.BooleanField(default=False) + strong = models.BooleanField(default=False) + + @property + def vertex_count(self): + return self.vertices.filter(graph=self).count() + + @property + def arc_count(self): + return self.vertices.filter(in_arcs__isnull=False).count() + # return Arc.objects.filter(vertex_in__graph=self).count() + + def get_properties(self): + return { + 'vertex': self.vertex_count, + 'arc': self.arc_count, + } + + def update(self): + vertices = self.vertices.all() + in_weight = [] + out_weight = [] + labels = [] + + for vertex in vertices: + labels.append(vertex.label) + in_weight.append(vertex.in_weight) + out_weight.append(vertex.out_weight) + + self.antimagic = len(in_weight) == len(set(in_weight)) and len(out_weight) == len(set(out_weight)) + self.strong = len(in_weight + out_weight) == len(set(in_weight + out_weight)) + self.save() + + def __str__(self): + return f"{self.graph_type}, {self.vertex_count};{self.arc_count}" + + +class Vertex(models.Model): + graph = models.ForeignKey(Graph, on_delete=models.CASCADE, blank=True, null=True, related_name="vertices") + index = models.IntegerField(default=0, null=True, blank=True) + label = models.IntegerField(default=0, null=True, blank=True) + + @property + def max_degree(self): + sum_in = self.in_arcs.all().count() + sum_out = self.out_arcs.all().count() + # in_arcs = Arc.objects.filter(vertex_in=self) + # sum_in = sum(1 for _ in in_arcs) + # out_arcs = Arc.objects.filter(vertex_out=self) + # sum_out = sum(1 for _ in out_arcs) + return sum_in if sum_in > sum_out else sum_out + + @property + def in_weight(self): + in_arcs = Arc.objects.filter(vertex_in=self) + return self.label + sum(arc.label for arc in in_arcs) + + @property + def out_weight(self): + out_arcs = Arc.objects.filter(vertex_out=self) + return self.label + sum(arc.label for arc in out_arcs) + + def get_properties(self): + return { + 'in_weight': self.in_weight, + 'out_weight': self.out_weight, + 'max_degree': self.max_degree, + } + + def __str__(self): + return f"{self.id}, {self.label}, {self.index}" + + +class Arc(models.Model): + vertex_in = models.ForeignKey(Vertex, on_delete=models.CASCADE, related_name='in_arcs') + vertex_out = models.ForeignKey(Vertex, on_delete=models.CASCADE, related_name='out_arcs') + label = models.IntegerField(default=0, null=True, blank=True) + + def __str__(self): + return f"{self.id}, ({self.vertex_in.label}, {self.vertex_out.label}) {self.label}" diff --git a/src/tests.py b/src/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/src/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/src/views.py b/src/views.py new file mode 100644 index 0000000..5b29c44 --- /dev/null +++ b/src/views.py @@ -0,0 +1,37 @@ +from django.views.generic import TemplateView + +from src.models import Graph, Vertex, Arc + + +class IndexView(TemplateView): + template_name = "index.html" + + def get_context_data(self): + return { + "graphs": [Graph.CYCLE, Graph.PATH], + } + + +class TypeView(TemplateView): + template_name = "type.html" + + def get_context_data(self, **kwargs): + return { + "kwargs": kwargs, + "graphs": Graph.objects.filter( + graph_type=kwargs.get("type") + ).order_by("binary"), + } + + +class InfoView(TemplateView): + template_name = "info.html" + + def get_context_data(self, **kwargs): + graph = Graph.objects.get(id=kwargs.get("info")) + return { + "arcs": Arc.objects.filter(vertex_in__graph=graph).order_by("id"), + "vertices": Vertex.objects.filter(graph=graph).order_by("id"), + "graph": graph, + "type_name": graph.graph_type, + } diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..c32036c --- /dev/null +++ b/templates/index.html @@ -0,0 +1,14 @@ + + + + + Beeebooo + + +{% for graph in graphs %} + +{% endfor %} + + \ No newline at end of file diff --git a/templates/info.html b/templates/info.html new file mode 100644 index 0000000..2097eea --- /dev/null +++ b/templates/info.html @@ -0,0 +1,98 @@ + + + + + Title + + +

INFO

+ + + + + + + + + + + + + + + + + + +
VrcholyArkyBinaryAntimagicSuperStrict
{{ graph.get_properties.vertex }}{{ graph.get_properties.arc }}{{ graph.binary }}{% if graph.antimagic %}{{ graph.antimagic }}{% else %}---{% endif %}{% if graph.strong %}{{ graph.strong }}{% else %}---{% endif %}
+ +
+ +{% for arc in arcs %} + {% if forloop.last and type_name == "cyklus" %} + {% if arc.vertex_out.id > arc.vertex_in.id %} + ({{ arc.vertex_out.label }})--{{ arc.label }}-->({{ arc.vertex_in.label }}) + {% else %} + ({{ arc.vertex_in.label }})<--{{ arc.label }}--({{ arc.vertex_out.label }}) + {% endif %} + {% elif forloop.last and type_name == "cesta" %} + {% if arc.vertex_out.id > arc.vertex_in.id %} + ({{ arc.vertex_out.label }})--{{ arc.label }}-->({{ arc.vertex_in.label }}) + {% else %} + ({{ arc.vertex_in.label }})<--{{ arc.label }}--({{ arc.vertex_out.label }}) + {% endif %} + {% else %} + {% if arc.vertex_out.id > arc.vertex_in.id %} + ({{ arc.vertex_in.label }})<--{{ arc.label }}-- + {% else %} + ({{ arc.vertex_out.label }})--{{ arc.label }}--> + {% endif %} + {% endif %} +{% endfor %} +
+{% for vertex in vertices %} + {{ vertex.get_properties.in_weight }} -------- +{% endfor %} +
+{% for vertex in vertices %} + {{ vertex.get_properties.out_weight }} -------- +{% endfor %} + + +

Arky

+ + + + + + + {% for arc in arcs %} + + + + + +{% endfor %} +
OUTINVáha
{{ arc.vertex_out.label }}{{ arc.vertex_in.label }}{{ arc.label }}
+

Váhy

+ + + + + + + + + {% for vertex in vertices %} + + + + + + + +{% endfor %} +
Váhaindexm_dOUTIN
{{ vertex.label }}{{ vertex.index }}{{ vertex.get_properties.max_degree }}{{ vertex.get_properties.out_weight }}{{ vertex.get_properties.in_weight }}
+ + + \ No newline at end of file diff --git a/templates/type.html b/templates/type.html new file mode 100644 index 0000000..9660df9 --- /dev/null +++ b/templates/type.html @@ -0,0 +1,32 @@ + + + + + Ahoj + + + + + + + + + + + + + + {% for graph in graphs %} + + + + + + + + + + {% endfor %} +
->VrcholyArkyBinaryAntimagicSuperStrict
o{{ graph.get_properties.vertex }}{{ graph.get_properties.arc }}{{ graph.binary }}{% if graph.antimagic %}{{ graph.antimagic }}{% else %}---{% endif %}{% if graph.strong %}{{ graph.strong }}{% else %}---{% endif %}
+ + \ No newline at end of file