Skip to content
Snippets Groups Projects
Commit c47a9f66 authored by Oliwer Mattsson's avatar Oliwer Mattsson :headphones:
Browse files
parents 68543cd5 2abed34f
No related branches found
No related tags found
No related merge requests found
#!/.venv/bin/python
# TODO
# Gör project_id dynamisk så att den uppdateras efter borttagning/addering av projekt.
# ---- IMPORTS ---- #
import os
import json
import pprint
import re
from operator import itemgetter
# ---- IMPORTS ---- #
def load(filename):
try:
with open(filename, 'r', encoding='utf-8') as file:
data = json.load(file)
file.close()
return data
except:
return None
def save(data):
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
file.close()
# Reload data
load()
# Get project by ID
def get_project(data, id):
for n in range(0, get_project_count(data)):
if data[n]['project_id'] == id:
return data[n]
# Get project count
def get_project_count(data):
return len(data)
# Get all unique techniques from project
def get_techniques(data):
techniques = []
for project in data:
for tech in project['techniques_used']:
if tech not in techniques:
techniques.append(tech)
techniques.sort()
return techniques
# Gets all unique techniques from all projects ! COULD USE SOME FILTERING !
def get_technique_stats(data):
technique_list = get_techniques(data)
technique_stats = {}
current_techniques = []
for technique in technique_list:
for project in data:
if technique in project['techniques_used']:
current_techniques.append({'id' : project['project_id'], 'name' : project['project_name']})
technique_stats.update({technique : current_techniques.copy()})
current_techniques.clear()
return technique_stats
# Fetches and sorts projects matching criteria from the specified list.
def search(data, sort_by='project_id', sort_order='desc', techniques=None, search=None, search_field=None):
results = []
# get it
for project in data:
results.append(project)
# sort it
results = sorted(results, key=itemgetter(sort_by))
# order it
if sort_order == 'asc': results.reverse()
# filter it (by techniques)
if techniques != None:
for technique in get_techniques(data):
for project in results:
if all(n in project['techniques_used'] for n in techniques):
pass
else:
results.pop(results.index(project))
# search for it
if search != None:
search_results = []
for project in results:
print(list(project.values()))
if search_field != None and search_field != "":
if search in project[search_field]:
search_results.append(project)
elif search_field == "":
results.clear()
else:
for substring in list(project.values()):
print(type(substring))
if type(substring) == str:
if substring.find(search) != -1:
search_results.append(project)
break
if type(substring) == int:
if str(substring).find(search) != -1:
search_results.append(project)
break
if type(substring) == list:
for subsubstring in substring:
if type(subsubstring) == str:
if subsubstring.find(search) != -1:
search_results.append(project)
break
if type(subsubstring) == int:
if str(subsubstring).find(search) != -1:
search_results.append(project)
break
pprint.pp(results)
return results
def cls():
os.system('cls' if os.name == 'nt' else 'clear')
pass
def new_project(data):
cls()
# ---- COLLECT INFO ----
project_title = input("Project title: ")
project_id = get_project_count(data)+1
techniques = input("\nWhat techniques does your project use? Write them out in the following format: python, java, html, css\n\nTechniques: ").replace(" ", "").lower().split(",")
description = input("Provide a description of your project: ")
url = input("Provide a link to the source code/demo of your project: ")
img_url = input("Image source (ex: logo.jpg): ")
# ---- COLLECT INFO ----
# lexicographical order sort aka alphabetical
techniques.sort()
new_project = {
"project_name": project_title,
"project_id": project_id,
"used_techniques": techniques,
"long_description": description,
"img_url": img_url,
"url": url
}
cls()
print("\n\nProject preview:\n")
pprint.pp(new_project)
option = int(input("\n1: Create\n2: Cancel\n> "))
if option == 1:
data.append(new_project)
save(data)
pass
def list_projects(data):
cls()
for project in data:
pprint.pp(project)
print("\n")
def edit_project(data, id):
while True:
if id > get_project_count(data) or id < 0:
print("Project ID doesn't exist.\n")
id = int(input("Project_ID to edit: "))
else:
cls()
project = get_project(data, id)
project.pop('project_id') # Project ID shouldn't be changed
print(f"Editing project: {project['title']}\n")
pprint.pp(project)
print("")
for field in enumerate(project):
print(f"{field[0]}: {field[1]}")
input("\nField to edit: ")
def delete_project(data):
pass
def menu(data):
menu_items = ["Add new project", "List projects", "Edit existing project", "Delete project", "Quit"]
menu_index = 0
while True:
cls()
titular = r"""
____ _ __ _ _
| _ \ ___ _ __ | |_ / _| ___ | | (_) ___
| |_) | / _ \ | '__| | __| | |_ / _ \ | | | | / _ \
| __/ | (_) | | | | |_ | _| | (_) | | | _ | | | (_) |
|_| \___/ |_| \__| |_| \___/ |_| (_) |_| \___/
"""
print(titular)
for i in menu_items:
print(f"{menu_items.index(i)+1}: {i}")
try:
option = int(input(f"> "))
if option == 1:
new_project(data)
elif option == 2:
list_projects(data)
input()
elif option == 3:
list_projects(data)
edit_project(data, int(input("Project_ID to edit: ")))
elif option == 4:
delete_project(data, int(input("Project_ID to delete: ")))
elif option == 5:
cls()
break
except:
print("")
def main():
data = load('MyPortfolio/data.json')
menu(data)
search(data, 'project_id', 'desc', [], 'csv')
if __name__ == "__main__":
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2011, IDA, Linköping University
# Copyright (C) 2011, Torbjörn Lönnemark <tobbez@ryara.net>
# Copyright (C) 2014, Daniel Persson
import unittest
import data # import the file with your implemented functions
import hashlib
import sys
from operator import itemgetter
# ----------- HELPER FUNCTIONS -----------
def print_tech_dict(d):
for k,v in d.items():
print("{}: {}".format(k,v))
for e in v:
print(e)
print()
def sort_dict(d,sort_key):
for k in d.keys():
d[k] = sorted(d[k], key = itemgetter(sort_key))
return d;
md5 = hashlib.md5
# ----------- TEST CLASS -----------
class DataTest(unittest.TestCase):
""" Subclass of the unittest.TestCase class
Define all tests as a method of this class. Each test must start with the
word test (ex test_load). Within each test method, various assertions
can be made, e.g. checking that what you are testing gives the expected
result.
Use the method self.assertEqual() to compare an expected and observed result.
Please refer to the unittest documentation for more information:
https://docs.python.org/3.7/library/unittest.html
To run the tests, have the files data_test.py, data.py and data.json in the
same catalog. data.py is the file with your implemented API functions.
Execute with:
$ python3 data_test.py
The test result is shown in the terminal.
"""
def setUp(self):
""" The setUp() method is called before every test_*-method. Use it to
prepare things that must always be done before a test is run, such as
loading the data.
"""
# The content in self.expected_data must match the content in data.json
# for the testing to work. Do NOT change the content or the file!
self.expected_data = [{'big_image': 'XXX',
'project_name': 'python data-module test script',
'course_name': 'OK\xc4NT',
'group_size': 2, 'end_date': '2009-09-06',
'techniques_used': ['python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 1,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-05',
'lulz_had': 'many'},
{'big_image': 'XXX',
'project_name': 'NEJ',
'course_name': 'OK\xc4NT',
'group_size': 4,
'end_date': '2009-09-08',
'techniques_used': ['c++', 'csv', 'python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 3,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-07',
'lulz_had': 'few'},
{'big_image': 'XXX',
'project_name': '2007',
'course_name': 'OK\xc4NT',
'group_size': 6,
'end_date': '2009-09-09',
'techniques_used': ['ada', 'python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 2,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-08',
'lulz_had': 'medium'},
{'big_image': 'XXX',
'project_name': ',',
'course_name': 'HOHO',
'group_size': 8,
'end_date': '2009-09-07',
'techniques_used': [],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': ' "',
'project_id': 4,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-06',
'lulz_had': 'over 9000'}
]
# Sort the expected data by project id
self.expected_data = sorted(self.expected_data, key=itemgetter('project_id'))
# Store the hardcoded expected results.
# Do NOT change this part
self.expected_technique_data = ['ada', 'c++', 'csv', 'python']
self.expected_technique_stat_data = {'python': [{'id': 2, 'name': '2007'},
{'id': 3, 'name': 'NEJ'},
{'id': 1, 'name': 'python data-module test script'}],
'csv': [{'id': 3, 'name': 'NEJ'}],
'c++': [{'id': 3, 'name': 'NEJ'}],
'ada': [{'id': 2, 'name': '2007'}]}
# Load the data using your implemented load function. The data is
# stored as a member of the class instance, so that it can be accessed
# in other methods of the class
self.loaded_data = sorted(data.load("data.json"), key=itemgetter('project_id'))
def test_load(self):
""" Test the implemented load function """
# Compare the loaded data with the expected data
self.assertEqual(self.loaded_data[0], self.expected_data[0])
# Test that loading a non-existing file returns None
self.assertEqual(data.load("/dev/this_file_does_not_exist"), None)
def test_get_project_count(self):
""" Test the implemented function get_project_count """
# Test that the correct number of projects are returned
self.assertEqual(data.get_project_count(self.loaded_data), 4)
def test_get_project(self):
""" Test the implemented function get_project """
# Try to get project 1, 2, 3 and 4 and check that a project with
# the correct project_id is returned.
self.assertEqual(data.get_project(self.loaded_data, 1)['project_id'], 1)
self.assertEqual(data.get_project(self.loaded_data, 2)['project_id'], 2)
self.assertEqual(data.get_project(self.loaded_data, 3)['project_id'], 3)
self.assertEqual(data.get_project(self.loaded_data, 4)['project_id'], 4)
# Try to get a non-existing project and check that None is returned
self.assertEqual(data.get_project(self.loaded_data, 42), None)
def test_search(self):
""" Test the implemented search function """
# Call search with no other parameters than the database.
# All projects should be returned
self.assertEqual(len(data.search(self.loaded_data)), 4)
# Search for projects with csv as technique.
# 1 project should be returned
self.assertEqual(len(data.search(self.loaded_data, techniques=['csv'])), 1)
# Search for projects including Python and sort them in ascending order.
# Ensure that returned projects are sorted by ascending dates
res = data.search(self.loaded_data, sort_order='asc',techniques=["python"])
self.assertEqual(res[0]['start_date'], '2009-09-05')
self.assertEqual(res[1]['start_date'], '2009-09-07')
self.assertEqual(res[2]['start_date'], '2009-09-08')
# Search for the term 'okänt' in three specified search fields. Sort
# results by end_date.
# Ensure that projects are returned in the correct order.
res = data.search(self.loaded_data,
sort_by="end_date",
search='okänt',
search_fields=['project_id','project_name','course_name'])
self.assertEqual(len(res), 3)
self.assertEqual(res[0]['project_id'], 2)
self.assertEqual(res[1]['project_id'], 3)
self.assertEqual(res[2]['project_id'], 1)
# Search for 'okänt' in specified search fields.
# Ensure correct number of results
res = data.search(self.loaded_data,
search="okänt",
search_fields=["project_id","project_name","course_name"])
self.assertEqual(len(res), 3)
# Search for 'okänt' in specified search fields, provide empty technique list
# Ensure correct number of results
res = data.search(self.loaded_data,
techniques=[],
search="okänt",
search_fields=["project_id","project_name","course_name"])
self.assertEqual(len(res), 3)
# Search for 'okänt', provide empty search fields list
# Ensure 0 results
res = data.search(self.loaded_data, search="okänt", search_fields=[])
self.assertEqual(len(res), 0)
# Search with results sorted by group size.
# Ensure results are in descending order
res = data.search(self.loaded_data, sort_by='group_size')
self.assertEqual(res[0]['project_id'], 4) #1
self.assertEqual(res[1]['project_id'], 2) #2
self.assertEqual(res[2]['project_id'], 3) #3
self.assertEqual(res[3]['project_id'], 1) #4
def test_get_techniques(self):
""" Test the implemented get_techniques function """
res = data.get_techniques(self.loaded_data)
self.assertEqual(res, self.expected_technique_data)
def test_get_technique_stats(self):
""" Test the implemented get_technique_stats function """
res = data.get_technique_stats(self.loaded_data)
res = sort_dict(res,'id')
self.expected_technique_stat_data = sort_dict(self.expected_technique_stat_data,'id')
self.assertEqual(res, self.expected_technique_stat_data)
if __name__ == '__main__':
print ("Test: ", md5(sys.argv[0].encode('UTF-8')).hexdigest())
print ("Test data:", md5(b"data.json").hexdigest())
print()
unittest.main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2011, IDA, Linköping University
# Copyright (C) 2011, Torbjörn Lönnemark <tobbez@ryara.net>
# Copyright (C) 2014, Daniel Persson
import unittest
import data # import the file with your implemented functions
import hashlib
import sys
from operator import itemgetter
# ----------- HELPER FUNCTIONS -----------
def print_tech_dict(d):
for k,v in d.items():
print("{}: {}".format(k,v))
for e in v:
print(e)
print()
def sort_dict(d,sort_key):
for k in d.keys():
d[k] = sorted(d[k], key = itemgetter(sort_key))
return d;
md5 = hashlib.md5
# ----------- TEST CLASS -----------
class DataTest(unittest.TestCase):
""" Subclass of the unittest.TestCase class
Define all tests as a method of this class. Each test must start with the
word test (ex test_load). Within each test method, various assertions
can be made, e.g. checking that what you are testing gives the expected
result.
Use the method self.assertEqual() to compare an expected and observed result.
Please refer to the unittest documentation for more information:
https://docs.python.org/3.7/library/unittest.html
To run the tests, have the files data_test.py, data.py and data.json in the
same catalog. data.py is the file with your implemented API functions.
Execute with:
$ python3 data_test.py
The test result is shown in the terminal.
"""
def setUp(self):
""" The setUp() method is called before every test_*-method. Use it to
prepare things that must always be done before a test is run, such as
loading the data.
"""
# The content in self.expected_data must match the content in data.json
# for the testing to work. Do NOT change the content or the file!
self.expected_data = [{'big_image': 'XXX',
'project_name': 'python data-module test script',
'course_name': 'OK\xc4NT',
'group_size': 2, 'end_date': '2009-09-06',
'techniques_used': ['python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 1,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-05',
'lulz_had': 'many'},
{'big_image': 'XXX',
'project_name': 'NEJ',
'course_name': 'OK\xc4NT',
'group_size': 4,
'end_date': '2009-09-08',
'techniques_used': ['c++', 'csv', 'python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 3,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-07',
'lulz_had': 'few'},
{'big_image': 'XXX',
'project_name': '2007',
'course_name': 'OK\xc4NT',
'group_size': 6,
'end_date': '2009-09-09',
'techniques_used': ['ada', 'python'],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': 'TDP003',
'project_id': 2,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-08',
'lulz_had': 'medium'},
{'big_image': 'XXX',
'project_name': ',',
'course_name': 'HOHO',
'group_size': 8,
'end_date': '2009-09-07',
'techniques_used': [],
'academic_credits': 'WUT?',
'small_image': 'X',
'long_description': 'no no no',
'course_id': ' "',
'project_id': 4,
'external_link': 'YY',
'short_description': 'no',
'start_date': '2009-09-06',
'lulz_had': 'over 9000'}
]
# Sort the expected data by project id
self.expected_data = sorted(self.expected_data, key=itemgetter('project_id'))
# Store the hardcoded expected results.
# Do NOT change this part
self.expected_technique_data = ['ada', 'c++', 'csv', 'python']
self.expected_technique_stat_data = {'python': [{'id': 2, 'name': '2007'},
{'id': 3, 'name': 'NEJ'},
{'id': 1, 'name': 'python data-module test script'}],
'csv': [{'id': 3, 'name': 'NEJ'}],
'c++': [{'id': 3, 'name': 'NEJ'}],
'ada': [{'id': 2, 'name': '2007'}]}
# Load the data using your implemented load function. The data is
# stored as a member of the class instance, so that it can be accessed
# in other methods of the class
self.loaded_data = sorted(data.load("data.json"), key=itemgetter('project_id'))
def test_load(self):
""" Test the implemented load function """
# Compare the loaded data with the expected data
self.assertEqual(self.loaded_data[0], self.expected_data[0])
# Test that loading a non-existing file returns None
self.assertEqual(data.load("/dev/this_file_does_not_exist"), None)
def test_get_project_count(self):
""" Test the implemented function get_project_count """
# Test that the correct number of projects are returned
self.assertEqual(data.get_project_count(self.loaded_data), 4)
def test_get_project(self):
""" Test the implemented function get_project """
# Try to get project 1, 2, 3 and 4 and check that a project with
# the correct project_id is returned.
self.assertEqual(data.get_project(self.loaded_data, 1)['project_id'], 1)
self.assertEqual(data.get_project(self.loaded_data, 2)['project_id'], 2)
self.assertEqual(data.get_project(self.loaded_data, 3)['project_id'], 3)
self.assertEqual(data.get_project(self.loaded_data, 4)['project_id'], 4)
# Try to get a non-existing project and check that None is returned
self.assertEqual(data.get_project(self.loaded_data, 42), None)
def test_search(self):
""" Test the implemented search function """
# Call search with no other parameters than the database.
# All projects should be returned
self.assertEqual(len(data.search(self.loaded_data)), 4)
# Search for projects with csv as technique.
# 1 project should be returned
self.assertEqual(len(data.search(self.loaded_data, techniques=['csv'])), 1)
# Search for projects including Python and sort them in ascending order.
# Ensure that returned projects are sorted by ascending dates
res = data.search(self.loaded_data, sort_order='asc',techniques=["python"])
self.assertEqual(res[0]['start_date'], '2009-09-05')
self.assertEqual(res[1]['start_date'], '2009-09-07')
self.assertEqual(res[2]['start_date'], '2009-09-08')
# Search for the term 'okänt' in three specified search fields. Sort
# results by end_date.
# Ensure that projects are returned in the correct order.
res = data.search(self.loaded_data,
sort_by="end_date",
search='okänt',
search_fields=['project_id','project_name','course_name'])
self.assertEqual(len(res), 3)
self.assertEqual(res[0]['project_id'], 2)
self.assertEqual(res[1]['project_id'], 3)
self.assertEqual(res[2]['project_id'], 1)
# Search for 'okänt' in specified search fields.
# Ensure correct number of results
res = data.search(self.loaded_data,
search="okänt",
search_fields=["project_id","project_name","course_name"])
self.assertEqual(len(res), 3)
# Search for 'okänt' in specified search fields, provide empty technique list
# Ensure correct number of results
res = data.search(self.loaded_data,
techniques=[],
search="okänt",
search_fields=["project_id","project_name","course_name"])
self.assertEqual(len(res), 3)
# Search for 'okänt', provide empty search fields list
# Ensure 0 results
res = data.search(self.loaded_data, search="okänt", search_fields=[])
self.assertEqual(len(res), 0)
# Search with results sorted by group size.
# Ensure results are in descending order
res = data.search(self.loaded_data, sort_by='group_size')
self.assertEqual(res[0]['project_id'], 4) #1
self.assertEqual(res[1]['project_id'], 2) #2
self.assertEqual(res[2]['project_id'], 3) #3
self.assertEqual(res[3]['project_id'], 1) #4
def test_get_techniques(self):
""" Test the implemented get_techniques function """
res = data.get_techniques(self.loaded_data)
self.assertEqual(res, self.expected_technique_data)
def test_get_technique_stats(self):
""" Test the implemented get_technique_stats function """
res = data.get_technique_stats(self.loaded_data)
res = sort_dict(res,'id')
self.expected_technique_stat_data = sort_dict(self.expected_technique_stat_data,'id')
self.assertEqual(res, self.expected_technique_stat_data)
if __name__ == '__main__':
print ("Test: ", md5(sys.argv[0].encode('UTF-8')).hexdigest())
print ("Test data:", md5(b"data.json").hexdigest())
print()
unittest.main()
File deleted
File deleted
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment