def open_dialog(window, grid): dialog = QtWidgets.QDialog(window) #with open('wator/gui/opensimulation.ui') as f: # uic.loadUi(f, dialog) #result = dialog.exec() #if result == QtWidgets.QDialog.Rejected: # return filename, _filter = QtWidgets.QFileDialog.getOpenFileName(None, "Open file", 'wator/gui/simulations/', "(*)") #filename = dialog.findChild(QtWidgets.QLineEdit, 'filenameLine').text() if filename == "": return #if not os.path.isfile(filename): #error = QtWidgets.QErrorMessage() #error.showMessage('File does not exist!') # error = QtWidgets.QMessageBox.critical(None, "Error", "File does not exist!", QtWidgets.QMessageBox.Ok) # error.exec() #return if os.path.getsize(filename) == 0: error = QtWidgets.QMessageBox.critical(None, "Error", "File is empty!", QtWidgets.QMessageBox.Ok) # error = QtWidgets.QErrorMessage() # error.showMessage('File is empty!') # error.exec() return try: array = numpy.loadtxt(filename, dtype=numpy.int8) except ValueError: #error = QtWidgets.QErrorMessage() #error.showMessage('File does not contains data for simulation!') #error.exec() error = QtWidgets.QMessageBox.critical(None, "Error", "File does not contains data for simulation!", QtWidgets.QMessageBox.Ok) return wator = WaTor(creatures=array) grid.array = wator.creatures grid.energy = wator.energies size = logical_to_pixels(grid.array.shape[0], grid.array.shape[1]) grid.setMinimumSize(*size) grid.setMaximumSize(*size) grid.resize(*size) grid.update()
def main(): app = QtWidgets.QApplication([]) window = QtWidgets.QMainWindow() with open('wator/static/ui/mainwindow.ui') as f: uic.loadUi(f, window) wator = WaTor(shape=(15, 15), nfish=10, nsharks=10) scroll_area = window.findChild(QtWidgets.QScrollArea, 'scrollArea') grid = GridWidget(wator.creatures, wator.energies) scroll_area.setWidget(grid) palette = window.findChild(QtWidgets.QListWidget, 'palette') for creature, image, index in ('Water', WATER_PATH, 0), ('Fish', FISH_PATH, 1), ('Shark', SHARK_PATH, -1): item = QtWidgets.QListWidgetItem(creature) icon = QtGui.QIcon(image) item.setIcon(icon) item.setData(VALUE_ROLE, index) palette.addItem(item) def item_activated(): for item in palette.selectedItems(): grid.selected = item.data(VALUE_ROLE) palette.itemSelectionChanged.connect(item_activated) palette.setCurrentRow(0) action = window.findChild(QtWidgets.QAction, 'actionNew') action.triggered.connect(lambda: new_dialog(window, grid)) action = window.findChild(QtWidgets.QPushButton, 'nextchrononButton') action.clicked.connect(lambda: tick(window, grid)) action = window.findChild(QtWidgets.QAction, 'actionSave') action.triggered.connect(lambda: save(grid)) action = window.findChild(QtWidgets.QAction, 'actionLoad') action.triggered.connect(lambda: load(grid)) action = window.findChild(QtWidgets.QAction, 'actionQuit') action.triggered.connect(lambda: exit()) action = window.findChild(QtWidgets.QAction, 'actionHelpAbout') action.triggered.connect(lambda: print_about()) window.show() return app.exec()
def test_shape_custom_age(): shape = (16, 16) age_fish = 2 age_shark = 20 wator = WaTor(shape=shape, nfish=16, nsharks=4, age_fish=age_fish, age_shark=age_shark) print(wator.creatures) assert wator.creatures.shape == shape assert wator.count_fish() == 16 assert wator.count_sharks() == 4 assert ((wator.creatures >= -age_shark) & (wator.creatures <= age_fish)).all()
def tick(window, grid): wator = WaTor(creatures=grid.array, energies=grid.energy) age_fish = window.findChild(QtWidgets.QSpinBox, 'fishBox').value() age_shark = window.findChild(QtWidgets.QSpinBox, 'sharkBox').value() energy_eat = window.findChild(QtWidgets.QSpinBox, 'eat_energyBox').value() wator.set_age_fish(age_fish) wator.set_age_shark(age_shark) wator.set_energy_eat(energy_eat) wator.tick() grid.array = wator.creatures grid.energy = wator.energies grid.update()
def new_dialog(window, grid): # Vytvorime novy dialog. # V dokumentaci maji dialogy jako argument `this`; # jde o "nadrazene" okno. dialog = QtWidgets.QDialog(window) # Nacteme layout z Qt Designeru. with open('wator/gui/newsimulation.ui') as f: uic.loadUi(f, dialog) # Zobrazime dialog. # Funkce exec zajisti modalitu (tzn. nejde ovladat zbytek aplikace, # dokud je dialog zobrazen) a vrati se az potom, co uzivatel dialog zavre. result = dialog.exec() # Vysledna hodnota odpovida tlacitku/zpusobu, kterym uzivatel dialog zavrel. if result == QtWidgets.QDialog.Rejected: # Dialog uzivatel zavrel nebo klikl na Cancel. return # Nacteni hodnot ze SpinBoxu cols = dialog.findChild(QtWidgets.QSpinBox, 'colsBox').value() rows = dialog.findChild(QtWidgets.QSpinBox, 'rowsBox').value() nfish = dialog.findChild(QtWidgets.QSpinBox, 'nfishBox').value() nsharks = dialog.findChild(QtWidgets.QSpinBox, 'nsharksBox').value() if cols == 0 or rows == 0: error = QtWidgets.QErrorMessage() error.showMessage('Number of columns or rows can\'t be 0!') error.exec() return wator = WaTor(shape=(rows, cols), nfish=nfish, nsharks=nsharks) # Vytvoreni nove mapy grid.array = wator.creatures grid.energy = wator.energies # Mapa muze byt jinak velka, tak musime zmenit velikost Gridu; # (tento kod pouzivame i jinde, meli bychom si na to udelat funkci!) size = logical_to_pixels(rows, cols) grid.setMinimumSize(*size) grid.setMaximumSize(*size) grid.resize(*size) # Prekresleni celeho Gridu grid.update()
def next_chronon(window, grid): wator = WaTor(creatures=grid.array, energies=grid.energy) age_fish = window.findChild(QtWidgets.QSpinBox, 'age_fishBox').value() age_shark = window.findChild(QtWidgets.QSpinBox, 'age_sharkBox').value() eat = window.findChild(QtWidgets.QSpinBox, 'energy_eatBox').value() wator.setAge_fish(age_fish) wator.setAge_shark(age_shark) wator.setEnergy_eat(eat) wator.tick() grid.array = wator.creatures grid.energy = wator.energies grid.update()
def simulation(window, grid, app): wator = WaTor(creatures=grid.array, energies=grid.energy) age_fish = window.findChild(QtWidgets.QSpinBox, 'age_fishBox').value() age_shark = window.findChild(QtWidgets.QSpinBox, 'age_sharkBox').value() eat = window.findChild(QtWidgets.QSpinBox, 'energy_eatBox').value() wator.setAge_fish(age_fish) wator.setAge_shark(age_shark) wator.setEnergy_eat(eat) a = 0 while a < 10: wator.tick() grid.array = wator.creatures grid.energy = wator.energies grid.update() time.sleep(1) app.processEvents() a += 1
def load(grid): file, _filter = QtWidgets.QFileDialog.getOpenFileName( None, "Load Simulation") try: array = numpy.loadtxt(file, dtype=numpy.int8) except FileNotFoundError: return except: QtWidgets.QMessageBox.critical(None, "Error", "Invalid file!", QtWidgets.QMessageBox.Ok) return wator = WaTor(creatures=array) grid.array = wator.creatures grid.energy = wator.energies size = GridWidget.logical_to_pixels(grid.array.shape[0], grid.array.shape[1]) grid.setMinimumSize(*size) grid.setMaximumSize(*size) grid.resize(*size) grid.update()
SIZE = 2048 SHAPE = (SIZE, SIZE) N = SIZE ** 2 // 3 @pytest.mark.timeout(5) def test_random_geenerator_speed(): for i in range(20): wator = WaTor(shape=SHAPE, nfish=N, nsharks=N) print(i) assert wator.count_fish() == N assert wator.count_sharks() == N # create this outside of test scope (not to be timed) WATOR = WaTor(shape=SHAPE, nfish=N, nsharks=N) @pytest.fixture def wator(): ''' A large wator with copies of global creatures and energies ''' return WaTor(numpy.copy(WATOR.creatures), energies=numpy.copy(WATOR.energies)) @pytest.mark.timeout(60) def test_tick_speed(wator): for i in range(4): wator.tick()
def main(): app = QtWidgets.QApplication([]) window = QtWidgets.QMainWindow() with open('wator/gui/mainwindow.ui') as f: uic.loadUi(f, window) # mapa zatim nadefinovana rovnou v kodu wator = WaTor(shape=(15, 20), nfish=10, nsharks=10) # ziskame oblast s posuvniky z Qt Designeru scroll_area = window.findChild(QtWidgets.QScrollArea, 'scrollArea') # dame do ni nas grid grid = GridWidget(wator.creatures, wator.energies) scroll_area.setWidget(grid) # ziskame paletu vytvorenou v Qt Designeru palette = window.findChild(QtWidgets.QListWidget, 'palette') for name, svg, num in ('Water', 'wator/gui/water.svg', 0),('Fish', 'wator/gui/fish.svg', 1),('Shark', 'wator/gui/shark.svg', -1): item = QtWidgets.QListWidgetItem(name) # vytvorime polozku icon = QtGui.QIcon(svg) # ikonu item.setIcon(icon) # priradime ikonu polozce item.setData(VALUE_ROLE, num) palette.addItem(item) # pridame polozku do palety def item_activated(): """Tato funkce se zavola, kdyz uzivatel zvoli polozku""" # Polozek muze obecne byt vybrano vic, ale v nasem seznamu je to # zakazano (v Designeru selectionMode=SingleSelection). # Projdeme "vsechny vybrane polozky", i kdyz vime ze bude max. jedna. for item in palette.selectedItems(): #print(item.data(VALUE_ROLE)) grid.selected = item.data(VALUE_ROLE) palette.itemSelectionChanged.connect(item_activated) palette.setCurrentRow(0) # aby to nesletelo, protoze neni nic vybrano # Napojeni signalu actionNew.triggered action1 = window.findChild(QtWidgets.QAction, 'actionNew') action1.triggered.connect(lambda: new_dialog(window, grid)) action2 = window.findChild(QtWidgets.QAction, 'actionNext_chronon') action2.triggered.connect(lambda: next_chronon(window, grid)) action3 = window.findChild(QtWidgets.QAction, 'actionSave') action3.triggered.connect(lambda: save_dialog(window, grid)) action4 = window.findChild(QtWidgets.QAction, 'actionOpen') action4.triggered.connect(lambda: open_dialog(window, grid)) action5 = window.findChild(QtWidgets.QAction, 'actionSim') action5.triggered.connect(lambda: simulation(window, grid, app)) action6 = window.findChild(QtWidgets.QAction, 'actionAbout') action6.triggered.connect(lambda: printAbout(window, grid)) init = window.findChild(QtWidgets.QSpinBox, 'energy_initialBox').value() grid.initEnergy = init window.show() return app.exec()
def test_tick_returns_self(): creatures = numpy.zeros((2, 2)) wator = WaTor(creatures) assert wator.tick() == wator
def test_ticking_full_of_sharks_starves_them(): creatures = numpy.full((2, 2), -1) wator = WaTor(creatures) assert (wator.tick().creatures == numpy.full((2, 2), -2)).all() wator.tick().tick().tick().tick() # total 5 times assert (wator.tick().creatures == numpy.zeros((2, 2))).all()
def test_ticking_full_of_fish_makes_them_older(): creatures = numpy.ones((2, 2)) wator = WaTor(creatures) for i in range(2, 6): assert (wator.tick().creatures == numpy.full((2, 2), i)).all()
def test_ticking_empty_does_nothing(): creatures = numpy.zeros((2, 2)) wator = WaTor(creatures) assert (wator.tick().creatures == creatures).all()
def test_random_geenerator_speed(): for i in range(20): wator = WaTor(shape=SHAPE, nfish=N, nsharks=N) print(i) assert wator.count_fish() == N assert wator.count_sharks() == N
def wator(): ''' A large wator with copies of global creatures and energies ''' return WaTor(numpy.copy(WATOR.creatures), energies=numpy.copy(WATOR.energies))
def test_shape_full_of_shark(): shape = (16, 16) wator = WaTor(shape=shape, nfish=0, nsharks=16 * 16) print(wator.creatures) assert wator.count_fish() == 0 assert wator.count_sharks() == 16 * 16