コード例 #1
0
def main():
    fh = IO()
    pda = PDA()
    automataFilePath = input('Enter the automata file path: ')
    lines = fh.readFile(automataFilePath)

    print('Automata File Successfully Read')

    inputString = input('Enter input String: ')
    inputString = inputString.rstrip()
    print('Details from Automata File: ')

    parsedLines = fh.parseFile(lines)
    print('States: ', parsedLines['states'])
    print('Input Symbols: ', parsedLines['input_symbols'])
    print('Stack Symbols: ', parsedLines['stack_symbols'])
    print('Initial State: ', parsedLines['initial_state'])
    print('Initial Stack Symbol: ', parsedLines['initial_stack'])
    print('Final States: ', parsedLines['final_states'])
    print('Productions List:')
    for production in parsedLines['productions']:
        print('\t', production)

    print('Details loaded')
    print('Computing the Transition Table:')
    pda.compute(inputString, parsedLines)
コード例 #2
0
	def __init__(self, sizesFilename):

		self.io = IO()

		dataLines = self.io.ReadFile(sizesFilename)

		self.sizes = Sizes(dataLines)
コード例 #3
0
ファイル: sokoban.py プロジェクト: frochet/IA-INGI2261
    def __init__(self, fileinit, filegoal):
        """
            filename has the form pathto/sokoInstxy 
            without the .goal or .init
            This constructor make the static board 
            and give the dynamic items (boxes, char)
            to the first state.
        """

        self.board = Board(filegoal)
        self.numbernodes = 0
        Io = IO(fileinit)
        Io.init_reader()
        self.boxes = []
        i = 0
        j = 0
        for line in Io.file:
            for elem in line:
                if elem == "$":
                    self.boxes.append(Box(i, j))
                elif elem == "@":
                    self.char = Char(i, j)
                j += 1
            j = 0
            i += 1
        self.direction = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT]

        self.goalsize = len(self.board.positionGoal)
        self.listCombi = heuristic.make_combi(self.board.positionGoal, self.goalsize)
        self.mini = 10000
        Problem.__init__(self, State(self.board, self.boxes, self.char, []))
コード例 #4
0
 def test_quality(self):
     log.info("Testing quality")
     log.info("Waiting for open signal")
     open_mould_signal = IO(Ports["open_signal"])
     open_mould_signal.wait_signal()
     log.info("Open signal acknowledged")
     log.info("Taking photo")
     test_quality_image = self.camera.take_photo()
     test_quality_image.save("full")
コード例 #5
0
 def __init__(self, user):
     self.bot = None
     self.lang = "en"
     self.url = f"https://www.tiktok.com/upload?lang={self.lang}"
     self.cookies = None
     self.userRequest = {"dir": "", "cap": "", "vidTxt": ""}
     self.video = None
     self.IO = IO("hashtags.txt", "schedule.csv")
     self.videoFormats = ["mov", "flv", "avi"]
     self.userPreference = user
コード例 #6
0
    def test_extraction(self):
        log.info("Testing extraction")

        log.info("Waiting for extraction signal")
        extration_complete_signal = IO(Ports["extraction_signal"])
        extration_complete_signal.wait_signal()
        log.info("Open signal acknowledged")
        log.info("Taking photo")
        test_extraction_image = self.camera.take_photo()
        test_extraction_image.save("empty")
コード例 #7
0
ファイル: Collect.py プロジェクト: davidsoncolin/IMS
	def cook(self, location, interface, attrs):
		if not self.useFrame(interface.frame(), attrs['frameRange']): return
		skelDict = interface.attr('skelDict')
		if not skelDict: return

		self.jointChannelFrames.append(skelDict['chanValues'].copy())

		if attrs['exportRule'] and self.useFrame(interface.frame(), attrs['exportRule']):
			from IO import IO
			exportPath = self.resolvePath(attrs['exportPath'])
			IO.save(exportPath, self.jointChannelFrames)
コード例 #8
0
def main() -> None:
    username, other = getUser()
    FICS = IO("freechess.org", 5000)
    FICS.login(username)
    send = Thread(target=client_send, args=(FICS, HOST))
    receive = Thread(target=client_receive, args=(FICS, ))
    send.start()
    receive.start()
    send.join()
    receive.join()
    resetLock()
    print("Ended")
コード例 #9
0
def client_send(server: IO, other: str):
    print("Sending has started")
    while not shouldExit():
        msg = input('')
        if msg == "$QUIT":
            stopAllThreads()
            continue
        print()
        try:
            server.tell(other, msg)
        except UnicodeEncodeError:
            print("Enter a unicode please")
コード例 #10
0
ファイル: StockAle.py プロジェクト: andystopford/StockAle
 def setup_year(self):
     """Populates current year from brew files"""
     io = IO(self)
     io.open_brews()
     try:
         self.model = self.model_dict[self.year]
     except:
         self.model = Model(self)
         self.model.setup()
     self.model.set_year(self.year)
     self.ui.yearView.setModel(self.model)
     self.ui.yearView.set_selection_model(self.model)
     self.ui.label_year.setText(str(self.year))
コード例 #11
0
ファイル: main.py プロジェクト: Kalmis/alykas-reseptikirja
	def __init__(self):
		
		# Testimoodi pois päältä oletuksena. Testimoodissa mm. AskUserInput metodit käyttävät kysymystä syötteenä.
		self.testMode = False
		
		self.mainMenuTitles = ["1. Varastotilanne", "2. Raaka-aineet", "3. Reseptit","4. Haku","5. Tallenna", "6. Lataa", "0. Sulje ohjelma"]
		self.storageMenuTitles = ["1. Kerro lisätietoja raaka-aineesta", "2. Näytä varastotilanne", "0. Takaisin"]
		self.ingredientsMenuTitles = ["1. Kerro lisätietoja raaka-aineesta", "2. Listaa raaka-aineet", "0. Takaisin"]
		self.recipesMenuTitles = ["1. Kerro lisätietoja reseptistä", "2. Listaa reseptit", "0. Takaisin"]
		self.searchMenuTitles = ["1. Kerro lisätietoja reseptistä", "2. Reseptit, joissa raaka-aine esiintyy", "3. Sopii allergikolle", "4. Reseptit, joihin varastotarvikkeet riittävät", "5. Reseptit, joista puuttuu N-määrä raaka-aineita varastosta", "6. Reseptit, joista löytyy N-määrä raaka-aineita varastosta", "0. Takaisin"]
		self.saveMenuTitles =  ["1. Tallenna kaikki", "2. Tallenna reseptit", "3. Tallenna raaka-aineet", "4. Tallenna varasto", "0. Takaisin"]
		self.loadMenuTitles =  ["1. Lataa kaikki", "2. Lataa reseptit", "3. Lataa raaka-aineet", "4. Lataa varasto", "0. Takaisin"]
		
		self.storageFile='varasto.csv'
		self.recipesFile='reseptit.txt'
		self.ingredientsFile='raaka_aineet.txt'
		self.IO = IO()
		
		
		self.ingredientsList = []
		self.recipesList = []
		self.storageList = []
		
		self.search = Search()
		
		self.loadFromFileToList(INGREDIENTS)
		self.loadFromFileToList(RECIPES)
		self.loadFromFileToList(STORAGE)
		self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
コード例 #12
0
ファイル: Algorithm.py プロジェクト: AndreasNel/deep-learning
 def save(self, history, batch_size, name):
     train_score = self.model.evaluate(self.x_train,
                                       self.y_train,
                                       batch_size=batch_size)
     test_score = self.model.evaluate(self.x_test,
                                      self.y_test,
                                      batch_size=batch_size)
     io = IO(history, train_score, test_score, name)
コード例 #13
0
def mainUserInput(server: IO, filename: str) -> None:
    rmtouch(filename)
    while True:
        name, msg = server.receive_tell()
        if msg is None:
            sleep(.1)
            continue
        with open(filename, 'a+') as fout:
            print("{}: {}".format(name, msg), file = fout, flush = True)
コード例 #14
0
def fileUserOutput(server: IO, filename = "1.game", recepient = P1) -> None:
    if VERBOSE: print(filename)
    server.tell(recepient, "Poker Game!! Let's Go!")
    if VERBOSE: print("Poker Game!! Let's Go!")
    with open(filename, 'r') as fin:
        prev = fin.readlines()[:-1]
    while True:
        with open(filename, 'r') as fin:
            new = fin.readlines()[:]
        differences = findDifference(prev[:], new[:])
        if differences != []:
            for s in differences:
                if "Let's Go!" in s:
                    continue
                if VERBOSE: print(s[:-1], flush = True)
                safestring = s[:-1]
                safestring = encodeStr(safestring)
                if VERBOSE: print("Safestring=", safestring)
                server.tell(recepient, safestring)
        prev = new[:]
コード例 #15
0
ファイル: Ensemble.py プロジェクト: DiggerForever/DPMF
 def predict(self):
     io = IO(None)
     rst = []
     rst.append(io.rawRead(PATH+'train/p1.csv'))
     rst.append(io.rawRead(PATH+'train/p2.csv'))
     rst.append(io.rawRead(PATH+'train/p3.csv'))
     # rst.append(io.rawRead(PATH+'train/p4.csv'))
     # rst.append(io.rawRead(PATH+'train/p5.csv'))
     # rst.append(io.rawRead(PATH+'train/p6.csv'))
     # rst.append(io.rawRead(PATH+'train/p7.csv'))
     # rst.append(io.rawRead(PATH+'train/p8.csv'))
     # rst.append(io.rawRead(PATH+'train/p9.csv'))
     # rst.append(io.rawRead(PATH+'train/p10.csv'))
     for i in range(len(rst)):
         rst[i] = [float(v) for v in rst[i]]
     rst = np.array(rst).mean(axis=0)
     self.testY = np.array(self.testY)
     print('*************************************')
     print('score last:'+str(roc_auc_score(self.testY,rst)))
     print('*************************************')
コード例 #16
0
def userInput(prompt: str, server: IO, user: str, filename: str) -> str:
    if prompt[-1] == '\n':
        prompt = prompt[:-1]
    if prompt[:3] == "fi\n":
        prompt = prompt[3:]
    sleep(.3)
    server.tell(user, encodeStr(prompt))
    with open(filename, 'r') as fin:
        prev = fin.readlines()[:]
    while True:
        sleep(.1)
        with open(filename, 'r') as fin:
            new = fin.readlines()[:]
        differences = findDifference(prev[:], new[:])
        if differences != []:
            for s in differences:
                if s != '' and user in s:
                    if VERBOSE: print(s)
                    return s[len(user + ": "):-1]
        prev = new[:]
コード例 #17
0
ファイル: puzzle.py プロジェクト: frochet/IA-INGI2261
 def print_conf(self, state, path=None):
     """
         print the state
     """   
     if path==None :
         for liste in state :
             for elem in liste :
                 sys.stdout.write(elem+" ")
             print("\n")
         print("\n")
     else :
         io = IO(path)
         io.init_writter()
         for liste in state :
             io.write_line(str(liste))
             io.write_line("\n")
         io.close()
コード例 #18
0
ファイル: puzzle.py プロジェクト: frochet/IA-INGI2261
 def parse_init(self,init, path=None):
     """
     Parse a representation given to a representation of an Object State
     @see State.state
     """
     if path == None:
         path = ""
         for list in init :
             for elem in list :
                 path += elem
     Io = IO(path)
     Io.init_reader()
     init = Io.file   
     self.initial = []
     for line in init:
             linestate = []
             
             for char in line:
                 if char != " " and char != "\n":
                     linestate += char
                 
             self.initial.append(linestate)
コード例 #19
0
ファイル: game.py プロジェクト: initrl/MinecraftRL
    def __init__(self):
        self.cons = IO()
        
        self.world = World()

        self.player = self.world.player

        self.player.update()
        self.world.updateAllC()
     
        self.colors = [libtcod.red, libtcod.green, libtcod.blue, libtcod.white,
                  libtcod.gray, libtcod.flame, libtcod.light_green, libtcod.yellow,
                  libtcod.gold, libtcod.darker_yellow]
コード例 #20
0
ファイル: Ensemble.py プロジェクト: DiggerForever/DPMF
 def bagging(self,sampling=0.7,round=150,persistance=False):
     self.finished = []
     rst = []
     io = IO(None)
     weights = []
     for i in range(round):
         if not self.parallel:
             X,y = customSampling(ratio=sampling,X=self.trainX,y=self.trainY)
             self.clf.setData(trainX=np.array(X),trainY=np.array(y))
             pred_train,pred_test,metric = self.clf.train()
             if X is not None:
                 del X
             if y is not None:
                 del y
             if not persistance:
                 rst.append(pred_test)
                 weights.append(metric)
             else:
                 io.rawWrite(list(pred_test),PATH+'train/pred_'+str(time.time())+'.csv')
         else:
             self.thread.addWorker(self.run,(i,sampling,rst,self.finished,round))
     if not persistance:
         if not self.parallel:
             weights_mean = np.array(weights).mean(axis=0)
             rst1 = np.array(rst).mean(axis=0)
             for pos in range(len(weights)):
                 weights[pos] = weights[pos] / float(np.array(weights).sum())
             for pos in range(len(weights)):
                 rst[pos] *= weights[pos]
             rst2 = np.array(rst).sum(axis=0)
             self.testY = np.array(self.testY)
             print('*************************************')
             print('Average auc:'+str(weights_mean))
             print('score after '+str(round)+' rounds of bagging with '+str(sampling)+' sampling and not weighted:'+str(roc_auc_score(self.testY,rst1)))
             print('score after '+str(round)+' rounds of bagging with '+str(sampling)+' sampling and weighted:'+str(roc_auc_score(self.testY,rst2)))
             print('*************************************')
         else:
             self.thread.start()
コード例 #21
0
ファイル: mainGUI.py プロジェクト: Kalmis/alykas-reseptikirja
 def initSettingsAndLists(self):
     ''' Tämä metodi alustaa tarvittavat muuttujat ja oliot sekä lataa reseptit, raaka-aineet ja varastotilanteen tiedostoista listoihin.'''
     
     self.storageFile= STORAGE
     self.recipesFile= RECIPES
     self.ingredientsFile= INGREDIENTS
     self.IO = IO()
     
     
     self.ingredientsList = []
     self.recipesList = []
     self.storageList = []
     
     self.search = Search()
     
     self.loadFromFileToList() # Sender on None, joten luetaan kaikki
     self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
コード例 #22
0
def main():
    manager = sql_manager.create_from_db_and_sql(db_name, create_sql, drop_sql, create_if_exists=False)
    manager.create_clients_table()
    controller = Controller(manager)
    io = IO(controller)
    io.main_menu()
コード例 #23
0
ファイル: main.py プロジェクト: Kalmis/alykas-reseptikirja
class Main(object):
	
	def __init__(self):
		
		# Testimoodi pois päältä oletuksena. Testimoodissa mm. AskUserInput metodit käyttävät kysymystä syötteenä.
		self.testMode = False
		
		self.mainMenuTitles = ["1. Varastotilanne", "2. Raaka-aineet", "3. Reseptit","4. Haku","5. Tallenna", "6. Lataa", "0. Sulje ohjelma"]
		self.storageMenuTitles = ["1. Kerro lisätietoja raaka-aineesta", "2. Näytä varastotilanne", "0. Takaisin"]
		self.ingredientsMenuTitles = ["1. Kerro lisätietoja raaka-aineesta", "2. Listaa raaka-aineet", "0. Takaisin"]
		self.recipesMenuTitles = ["1. Kerro lisätietoja reseptistä", "2. Listaa reseptit", "0. Takaisin"]
		self.searchMenuTitles = ["1. Kerro lisätietoja reseptistä", "2. Reseptit, joissa raaka-aine esiintyy", "3. Sopii allergikolle", "4. Reseptit, joihin varastotarvikkeet riittävät", "5. Reseptit, joista puuttuu N-määrä raaka-aineita varastosta", "6. Reseptit, joista löytyy N-määrä raaka-aineita varastosta", "0. Takaisin"]
		self.saveMenuTitles =  ["1. Tallenna kaikki", "2. Tallenna reseptit", "3. Tallenna raaka-aineet", "4. Tallenna varasto", "0. Takaisin"]
		self.loadMenuTitles =  ["1. Lataa kaikki", "2. Lataa reseptit", "3. Lataa raaka-aineet", "4. Lataa varasto", "0. Takaisin"]
		
		self.storageFile='varasto.csv'
		self.recipesFile='reseptit.txt'
		self.ingredientsFile='raaka_aineet.txt'
		self.IO = IO()
		
		
		self.ingredientsList = []
		self.recipesList = []
		self.storageList = []
		
		self.search = Search()
		
		self.loadFromFileToList(INGREDIENTS)
		self.loadFromFileToList(RECIPES)
		self.loadFromFileToList(STORAGE)
		self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
		

		
	def openFileUTF8(self,file):
		
		try:
			fileIO = codecs.open(file, "r", "utf-8")
			return fileIO
		except IOError:
			print("Tiedoston",file,"avaaminen ei onnistu.") 
			return 0
	
	def loadFromFileToList(self, listType):
		
		try:		
			if listType == INGREDIENTS:
				self.ingredientsList = []
				fileIO = self.openFileUTF8(self.ingredientsFile)
				self.ingredientsList, self.ingredientsSuccess, self.ingredientsError = self.IO.loadIngredients(fileIO)
			elif listType == RECIPES:
				self.recipesList = []
				fileIO = self.openFileUTF8(self.recipesFile)
				self.recipesList, self.recipesSuccess, self.recipesError = self.IO.loadRecipes(fileIO, self.ingredientsList)
			elif listType == STORAGE:
				self.storageList = []
				fileIO = self.openFileUTF8(self.storageFile)
				self.storageList, self.storageSuccess, self.storageError = self.IO.loadStorage(fileIO, self.ingredientsList)
			else:
				print("Tuntematon tyyppi")
				return -1
				
		except CorruptedFileError as e:
			fileIO.close()
			print(str(e))
			exit()

			
		fileIO.close()
				
	def printList(self, listToPrint, listType):
		
		if listType == INGREDIENTS:
			for i in listToPrint:
				print(i.getName()+ i.getAllergensStr())
		elif listType == RECIPES:
			for i in listToPrint:
				print(i.getName(), i.getTimeStr()+",", i.getOutcomeStr())
		elif listType == STORAGE:
			for i in listToPrint:
				print(i.getName() + ",", i.getQuantity(), i.getUnit()) 
		else:
			print("Tuntematon tyyppi")
			return -1
		
	def askNameAndPrintMoreInfo(self, listType):
		
		if listType == INGREDIENTS:
			userInput = self.askUserInputText("Raaka-aineen nimi > ")
			searchList = self.ingredientsList
		elif listType == RECIPES:
			userInput = self.askUserInputText("Reseptin nimi > ")
			searchList = self.recipesList
		elif listType == STORAGE:
			userInput = self.askUserInputText("Varastoidun raaka-aineen nimi > ")
			searchList = self.storageList			
		else:
			print("Tuntematon tyyppi")
			return -1
		result = self.search.searchFromList(userInput, searchList)
		if result != 0:
			print(result)
		else:
			print("Vastaavuutta ei löytynyt.")
	
	
	def runMenu(self, menuTitles):
		print("")
		for i in menuTitles:
			print(i)
		while True:
			userInput = self.askUserInputInt("Valintasi > ")
			if userInput >= 0 and userInput < len(menuTitles):
				return userInput
			else:
				print("Virheellinen valinta")

	def askUserInputText(self,question):
		
		userInput = input(question)
		return userInput	
	
	def askUserInputInt(self,question):

		# Testimoodissa käytetään argumenttia syötteenä.
		if self.testMode:
			userInput = question
		else:
			userInput = input(question) 
		while True:
			try:
				userInput = int(userInput)
				return(userInput)
			except ValueError:  
				print("Syöte ei kokonaisluku")
			userInput = input(question) 
			
	def askUserInputFloat(self,question):
		# Testimoodissa käytetään argumenttia syötteenä.
		if self.testMode:
			userInput = question
		else:
			userInput = input(question)
		
		while True:
			try:
				userInput = float(userInput)
				return(userInput)
			except ValueError:  
				print("Syöte ei desimaaliluku")
			userInput = input(question)

	def mainMenu(self):
		
		while True:
			userChoice = self.runMenu(self.mainMenuTitles)
			if userChoice == 1:
				self.storageMenu()
			elif userChoice == 2:
				self.ingredientsMenu()
			elif userChoice == 3:
				self.recipesMenu()
			elif userChoice == 4:
				self.searchMenu()
			elif userChoice == 5:
				self.saveMenu()
			elif userChoice == 6:
				self.loadMenu()
			elif userChoice == 0:
				return 0 

	def storageMenu(self):
		
		while True:
			userChoice = self.runMenu(self.storageMenuTitles)
			if userChoice == 1:
				self.askNameAndPrintMoreInfo(STORAGE)
			elif userChoice == 2:
				self.printList(self.storageList, STORAGE)
			elif userChoice == 0:
				return 0 
		
	def ingredientsMenu(self):
		while True:
			userChoice = self.runMenu(self.ingredientsMenuTitles)
			if userChoice == 1:
				self.askNameAndPrintMoreInfo(INGREDIENTS)
			elif userChoice == 2:
				self.printList(self.ingredientsList, INGREDIENTS)
			elif userChoice == 0:
				return 0   
		
	def recipesMenu(self):
		
		while 1:
			userChoice = self.runMenu(self.recipesMenuTitles)
			if userChoice == 1:
				self.askNameAndPrintMoreInfo(RECIPES)
			elif userChoice == 2:
				self.printList(self.recipesList, RECIPES)
			elif userChoice == 0:
				return 0   
		
	def searchMenu(self):
		
		while 1:
			userChoice = self.runMenu(self.searchMenuTitles)
			if userChoice == 1:
				self.askNameAndPrintMoreInfo(RECIPES)
			elif userChoice == 2:
				ingredientStr = self.askUserInputText("Raaka-aine > ")
				recipesFound = self.search.searchIncludesIngredient(ingredientStr, self.recipesList)
				self.printList(recipesFound, RECIPES)
			elif userChoice == 3:
				allergenStr = self.askUserInputText("Allergeeni > ")
				recipesFound = self.search.searchNoAllergen(allergenStr, self.recipesList)
				self.printList(recipesFound, RECIPES)
			elif userChoice == 4:
				recipesFound = self.search.searcForhRecipesNIngredientsInStorage(self.recipesList, 0, self.storageList, True)
				self.printList(recipesFound, RECIPES)
			elif userChoice == 5:
				N = self.askUserInputInt("Monta raaka-ainetta saa puuttua varastosta > ")
				recipesFound = self.search.searcForhRecipesNIngredientsInStorage(self.recipesList, N, self.storageList, True)
				self.printList(recipesFound, RECIPES)
			elif userChoice == 6:
				N = self.askUserInputInt("Monta raaka-ainetta löydyttävä varastosta > ")
				recipesFound = self.search.searcForhRecipesNIngredientsInStorage(self.recipesList, N, self.storageList, False)
				self.printList(recipesFound, RECIPES)
			elif userChoice == 0:
				return 0   
		
	def saveMenu(self):  
        
		while 1:
			userChoice = self.runMenu(self.saveMenuTitles)
			if userChoice == 1:
				self.IO.saveRecipes(self.recipesFile, self.recipesList)
				self.IO.saveIngredients(self.ingredientsFile, self.ingredientsList)
				self.IO.saveStorage(self.storageFile, self.storageList)
			elif userChoice == 2:
				self.IO.saveRecipes(self.recipesFile, self.recipesList)
			elif userChoice == 3:
				self.IO.saveIngredients(self.ingredientsFile, self.ingredientsList)
			elif userChoice == 4:
				self.IO.saveStorage(self.storageFile, self.storageList)
			elif userChoice == 0:
				return 0 

	def loadMenu(self):
        
		while 1:
			userChoice = self.runMenu(self.loadMenuTitles)
			if userChoice == 1:
				self.loadFromFileToList(INGREDIENTS)
				self.loadFromFileToList(RECIPES)
				self.loadFromFileToList(STORAGE)
				self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
			elif userChoice == 2:
				self.loadFromFileToList(RECIPES)
			elif userChoice == 3:
				self.loadFromFileToList(INGREDIENTS)
				self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
			elif userChoice == 4:
				self.loadFromFileToList(STORAGE)
			elif userChoice == 0:
				return 0 
コード例 #24
0
ファイル: mainGUI.py プロジェクト: Kalmis/alykas-reseptikirja
class MainGUI(QMainWindow, Ui_MainWindow):
    ''' Tämä luokka perii pyqt:n QMainWindow luokan sekä QT Designerilla luodun Ui_MainWindow luokan, joka on moduulissa GUIDesign.
    Ui_MainWindow luokka sisältää graafisen käyttöliittymän designin.
    
    Luokka sisältää paljon metodeja, joilla tehdään muutoksia, kun käyttöliittymällä tapahtuu muutoksia. Metodit voidaan jakaa karkeasti osiin
    
    Metodit:
        :init*: Luokan luomisen yhteydessä asetetaan nappuloiden toiminnallisuudet, ladataan tiedostoja ym.
        :populate*: Piirretään data johonkin tauluun
        :save*: Tallennetaan muuttunutta dataa
        :add*: Lisätään uusi ohje/raaka-aine/ym.
        :get*InDataListForTable: Metodit palauttavat niille annetun listan olennaisimmat tiedot "data" tyyppinä, joka voidaan antaa populateTableWith() metodille populoitavaksi
    
    '''
    
    def __init__(self):
        ''' Kutsuu Ui_MainWindow luokan konstruktoria, käyttöliittymän rakentamiseksi. Tämän lisäksi kutsutaan muita init metodeja, 
        joilla mm. määritellään painikkeiden toiminnalisuudet ja ladataan tarvittavat tiedot tiedostoista
        '''
        super().__init__()
        
        self.setupUi(self)
        self.initSettingsAndLists()
        self.initTablesAndLists()
        self.initToEditVariables()
        self.initLineEdits()
        self.initButtons()
        self.populateAllMainTables()
    
    def initSettingsAndLists(self):
        ''' Tämä metodi alustaa tarvittavat muuttujat ja oliot sekä lataa reseptit, raaka-aineet ja varastotilanteen tiedostoista listoihin.'''
        
        self.storageFile= STORAGE
        self.recipesFile= RECIPES
        self.ingredientsFile= INGREDIENTS
        self.IO = IO()
        
        
        self.ingredientsList = []
        self.recipesList = []
        self.storageList = []
        
        self.search = Search()
        
        self.loadFromFileToList() # Sender on None, joten luetaan kaikki
        self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
    
    def initButtons(self):
        ''' Tässä metodissa määritellään käyttöliittymän painikkeiden toiminallisuudet'''
        
        #Varastonäkymä
        self.buttonSaveStorageInfo.clicked.connect(self.saveStorageEdit)
        self.buttonPopulateStorage.clicked.connect(self.populateStorageTable)

        #Raak-ainenäkymä
        self.buttonPopulateIngredients.clicked.connect(self.populateIngredientsTable)
        self.buttonSaveIngredientInfo.clicked.connect(self.saveIngredientsEdit)
        
        #Reseptinäkymä
        self.buttonPopulateRecipes.clicked.connect(self.populateRecipesTable)
        self.buttonSaveRecipesInfo.clicked.connect(self.saveRecipesEdit)
        self.buttonSaveRecipeIngredient.clicked.connect(self.saveRecipesIngredientEdit)
        self.buttonSaveRecipeInstruction.clicked.connect(self.saveRecipesInstructionsEdit)
        self.buttonCreateNewRecipe.clicked.connect(self.showCreateNewRecipeDialog)
        self.buttonNewRecipeIngredient.clicked.connect(self.addNewRecipeIngredient)
        self.buttonNewRecipeInstruction.clicked.connect(self.addNewRecipeInstruction)
        self.buttonDeleteRecipeIngredient.clicked.connect(self.deleteRecipeIngredient)
        self.buttonDeleteRecipeInstruction.clicked.connect(self.deleteRecipeInstruction)
        
        #Haku näkymä
        
        self.buttonSearch.clicked.connect(self.populateSearchTable)
        self.checkMissingN.stateChanged.connect(self.checkStateChanged)
        self.checkFoundN.stateChanged.connect(self.checkStateChanged)
        
        #Asetukset näkymä
        self.buttonLoadAll.clicked.connect(self.loadFromFileToList)
        self.buttonLoadIngredients.clicked.connect(self.loadFromFileToList)
        self.buttonLoadRecipes.clicked.connect(self.loadFromFileToList)
        self.buttonLoadStorage.clicked.connect(self.loadFromFileToList)
        
        self.buttonSaveAll.clicked.connect(self.saveToFile)
        self.buttonSaveIngredients.clicked.connect(self.saveToFile)
        self.buttonSaveRecipes.clicked.connect(self.saveToFile)
        self.buttonSaveStorage.clicked.connect(self.saveToFile)
        
           
    def initTablesAndLists(self):
        ''' Tässä metodissa määritellään käyttöliittymän taulukkojen toiminnallisuudet, esim. kun taulukon riviä klikataan'''
        
        self.storageTable.clicked.connect(self.populateStorageEditFields)
        self.ingredientsTable.clicked.connect(self.populateIngredientsEditFields)
        
        #Reseptinäkymä
        self.recipesTable.clicked.connect(self.populateRecipesEditFields)
        self.recipeIngredientsTable.clicked.connect(self.populateRecipesIngredientEditFields)
        self.recipeInstructionsTable.clicked.connect(self.populateRecipesInstructionsEditFields)
    
    def initLineEdits(self):
        ''' Tässä metodissa alustetaan tarvittavat validaattorit sekä asetetaan nämä validaattorit käyttöön käyttöliittymän
        tekstikentille. 
        
        Käytettävät validaattorit ovat
        :min2char: vähintään 2 merkkiä pitkä
        :min1tomax10char: 1-10 merkkiä aakkosia
        :float2decimals: desimaaliluku, jossa 2 desimaalia
        :onlyint: ainoastaan kokonaislukuja
        '''
        # Validaattoreiden alustaminen
        min2char = QRegExpValidator(QRegExp("^[\w\s]{2,}$"))
        min1tomax10char = QRegExpValidator(QRegExp("^[a-zA-Z]{1,10}$"))
        float2decimals = QDoubleValidator(0.00,999999999.00,2)
        onlyint = QIntValidator()
        
        #Varastosivujen tekstikenttien validaattorit
        self.storageQuantity.setValidator(float2decimals)
        self.storageName.setValidator(min2char)
        self.storageUnit.setValidator(min1tomax10char)
        
        #Raaka-ainesivun validaattorit. Allergeenit ja resepti ei pakollisia.
        self.ingredientName.setValidator(min2char)
        self.ingredientDensity.setValidator(float2decimals)
        
        #Reseptisivun validaattorit
        self.recipeName.setValidator(min2char)
        self.recipeTime.setValidator(onlyint)
        self.recipeOutcomeSize.setValidator(float2decimals)
        self.recipeOutcomeUnit.setValidator(min1tomax10char)
        
        self.recipeIngredientQuantity.setValidator(float2decimals)
        self.recipeIngredientUnit.setValidator(min1tomax10char)
        
        
    def initToEditVariables(self):
        ''' Tässä metodissa alustetaan apumuuttujat, joilla pidetään kirjaa mikä rivi mistäkin taulukosta on valittuna. 
        Tätä tietoa tarvitaan taulukon tietojen muuttamisessa, esim. reseptin nimen.
        '''
        self.ingredientToEdit = None
        self.recipeToEdit = None
        self.recipeIngredientToEdit = None
        self.recipeInstructionToEdit = None
        self.storageToEdit = None
    
    def initDialogLineEdits(self):
        ''' Tässä metodissa alustetaan tarvittavat validaattorit sekä asetetaan nämä validaattorit käyttöön käyttöliittymän 
        "Uusi resepti" dialogin tekstikenttiin
        '''
        
        min2char = QRegExpValidator(QRegExp("^[\w\s]{2,}$"))
        min1tomax10char = QRegExpValidator(QRegExp("^[a-zA-Z]{1,10}$"))
        float2decimals = QDoubleValidator(0.00,999999999.00,2)
        onlyint = QIntValidator()
        
        self.recipeDialog.dialogName.setValidator(min2char)
        self.recipeDialog.dialogTime.setValidator(onlyint)
        self.recipeDialog.dialogOutcomeSize.setValidator(float2decimals)
        self.recipeDialog.dialogOutcomeUnit.setValidator(min1tomax10char)
        
        self.recipeDialog.dialogIngredient.setValidator(min2char)
        self.recipeDialog.DialogQuantity.setValidator(float2decimals)
        self.recipeDialog.dialogUnit.setValidator(min1tomax10char)
        
        self.recipeDialog.dialogInstruction.setValidator(min2char)

    def populateAllMainTables(self):
        ''' Tämä metodi kutsuu kaikkien päätaulukoiden (reseptit, varastotilanne, raaka-aineet) populointimetodeja'''
        
        self.populateStorageTable()
        self.populateIngredientsTable()
        self.populateRecipesTable()
        
    def populateTableWithData(self, table, data):
        ''' Tämä metodi populoi annettuun QTableWidget tauluun annetun datan. Datan tulee olla muotoa esim.
        data = [ ['Nimi','Määrä'], ['Kala', 'Peruna'], [5,3] ]
        
        Taulun sisältö tyhjennetään aluksi, asetetaan asetetaan sarakkeiden ja rivien lukumäärät. Tämän jälkeen
        taulu populoidaan datalla, jonka jällkeen kolumnien leveydet skaalataan sisällölle sopivaksi.
        '''
        
        table.clear()
        table.setRowCount(len(data[1]))
        table.setColumnCount(len(data[0]))
        table.setHorizontalHeaderLabels(data[0])
        
        data = iter(data)
        next(data) # Skipataan eka, koska ne on headerit
        for n, columnData in enumerate(data):
            for m, item in enumerate(columnData):
                newitem = QTableWidgetItem(item)
                table.setItem(m, n, newitem)
            
        table.resizeColumnsToContents()
        table.resizeRowsToContents()
        table.clear
        table.horizontalHeader().setStretchLastSection(True)
        
    def populateSearchTable(self):
        ''' Tämä metodi populoi datan hakunäkymän taulukkoon. Tätä metodia kutsuu hakunäkymän "Hae" painike.
        
        Hakunäkymällä on mahdollista valita nolla tai useampi hakuvaihtoehto, tämä metodi sisältää myös logiikan 
        valittujen vaihtoehtojen tarkastamiselle sekä oikean hakutuloksen saamiseksi.
        
        Haku hyödyntää Search luokan metodeja, jotka palauttavat listan resepteistä, jotka täyttävät hakukriteerin. 
        Hakulogiikka on ns. iteratiivinen ja alussa Search luokan metodeille annetaan listana kaikki tunnetut reseptit,
        mahdollinen seuraava haku kuitenkin tehdään edellisen haun palauttamasta listasta, jolloin lopuksi listassa on enää kaikki
        hakutulokset täyttävät reseptit.
        
        '''
        
        searchList = self.recipesList
        if self.checkName.isChecked():
            searchList = self.search.searchFromList(self.searchName.text(), searchList)
        if self.checkAllergen.isChecked():
            searchList = self.search.searchNoAllergen(self.searchAllergen.text(), searchList)
        if self.checkIngredient.isChecked():
            searchList = self.search.searchIncludesIngredient(self.searchIngredient.text(), searchList)
        if self.checkFoundN.isChecked():
            searchList = self.search.searcForhRecipesNIngredientsInStorage(searchList, self.spinFoundN.value(), self.storageList, False)
        elif self.checkMissingN.isChecked():
            print(self.spinMissingN.value())
            searchList = self.search.searcForhRecipesNIngredientsInStorage(searchList, self.spinMissingN.value(), self.storageList, True)
        
        if len(searchList)>0:
            data = self.getRecipesInDataListForTable(searchList)
            self.populateTableWithData(self.searchTable, data)
        else:
            self.statusBar().showMessage("Reseptejä ei löytynyt hakuehdoilla")
            self.searchTable.clearContents()
                
    def populateStorageTable(self):
        ''' Tämä metodi populoi varastolistaus tauluun kaikki varastossa olevat raaka-aineet'''
        
        data = self.getIngredientContainersInDataListForTable(self.storageList)
        self.populateTableWithData(self.storageTable,data)
        self.statusBar().showMessage("Varastolistaus päivitetty")
        
    def populateStorageEditFields(self,mi):
        ''' Tämä metodi populoi varastonäkymällä olevat tekstikentät, joilla voi muokata varastossa olevaa raaka-ainetta.
        Tätä metodia kutsutaan, kun varastolistauksessa klikataan riviä.
        
        Rivin indeksi tallennetaan self.storageToEdit muuttujaan, jotta muutoksia tallennettaessa tiedetään
        mitä varasto raaka-ainetta täytyy muokata
        
        Args:
            :mi: mi muuttuja/olio, joka sisältää klikatun rivin ja kolumnin indeksin.
        '''
        
        if mi.row() >= len(self.storageList):
            QMessageBox.warning(self, "Riviä ei voitu valita", "Päivitä listaus!", QMessageBox.Ok, QMessageBox.Ok)
            self.storageToEdit = None
        else:
            ingredient = self.storageList[mi.row()]
            self.storageName.setText(ingredient.getName())
            self.storageQuantity.setText(str(ingredient.getQuantityStr()))
            self.storageUnit.setText(ingredient.getUnit())
            self.storageToEdit = mi.row()

    def populateIngredientsTable(self):
        ''' Tämä metodi populoi raaka-ainelistaus tauluun kaikki tiedetyt raaka-aineet '''
        
        data = self.getIngredientsInDataListForTable(self.ingredientsList)
        self.populateTableWithData(self.ingredientsTable, data)
        self.statusBar().showMessage("Raaka-ainelistaus päivitetty")
        
    def populateIngredientsEditFields(self,mi):
        ''' Tämä metodi populoi raaka-ainenäkymällä olevat tekstikentät, joilla voi muokata raaka-aineen tietoja.
        Tätä metodia kutsutaan, kun raaka-ainelistaus taulua klikataan.
        
        Rivin indeksi tallennetaan self.ingredientToEdit muuttujaan, jotta muutoksia tallennettaessa tiedetään
        mitä raaka-ainetta täytyy muokata.
        
        Args:
            :mi: mi muuttuja/olio, joka sisältää klikatun rivin ja kolumnin indeksin.
        '''
        
        if mi.row() >= len(self.ingredientsList):
            QMessageBox.warning(self, "Riviä ei voitu valita", "Päivitä listaus!", QMessageBox.Ok, QMessageBox.Ok)
            self.ingredientToEdit = None
        else:
            ingredient = self.ingredientsList[mi.row()]
            self.ingredientName.setText(ingredient.getName())
            self.ingredientDensity.setText(ingredient.getDensityGUI())
            self.ingredientAllergens.setText(ingredient.getAllergensGUI())
            self.ingredientRecipe.setText(ingredient.getRecipeGUI())
            self.ingredientToEdit = mi.row()
           
    def populateRecipesTable(self):
        ''' Tämä metodi populoi reseptilistaus tauluun kaikki tiedetyt reseptit '''
        
        data = self.getRecipesInDataListForTable(self.recipesList)
        self.populateTableWithData(self.recipesTable, data)
        self.statusBar().showMessage("Reseptilistaus päivitetty")
        
    def populateRecipesInstructionsTable(self):
        ''' Tämä metodi populoi reseptinäkymällä reseptin ohjeet tauluun. 
        Tätä metodia kutsutaan, kun reseptilistaus taulua klikataan.
        
        Oikean reseptin löytämiseksi hyödynnetään self.recipeToEdit muuttujaa.
        '''
        self.clearRecipeEditLineEdits()
        recipe = self.recipesList[self.recipeToEdit]
        data = [['Ohje'], recipe.getInstructions()]
        self.populateTableWithData(self.recipeInstructionsTable, data)
            
    def populateRecipesIngredientsTable(self):
        ''' Tämä metodi populoi reseptinäkymällä reseptin raaka-aineet tauluun. 
        Tätä metodia kutsutaan, kun reseptilistaus taulua klikataan.
        
        Oikean reseptin löytämiseksi hyödynnetään self.recipeToEdit muuttujaa.
        '''
        self.clearRecipeEditLineEdits()
        recipe = self.recipesList[self.recipeToEdit]
        data = self.getIngredientContainersInDataListForTable(recipe.getIngredients())
        self.populateTableWithData(self.recipeIngredientsTable, data)
            
    def populateRecipesEditFields(self,mi):
        ''' Tämä metodi populoi reseptinäkymällä olevat reseptin tekstikentät sekä tyhjentää reseptin raaka-aine ja
        ohje muokkaustekstikentät sekä kutuu metodeja, joilla populoidaan reseptin raaka-aine ja ohjetaulut.
        
        Tätä metodia kutsutaan, kun reseptilistaus taulua klikataan.
        
        Rivin indeksi tallennetaan self.recipeToEdit muuttujaan, jotta muutoksia tallennettaessa tiedetään
        mitä reseptiä täytyy muokata. 
        
        Args:
            :mi: mi muuttuja/olio, joka sisältää klikatun rivin ja kolumnin indeksin.
        '''
        
        if mi.row() >= len(self.ingredientsList):
            QMessageBox.warning(self, "Riviä ei voitu valita", "Päivitä listaus!", QMessageBox.Ok, QMessageBox.Ok)
            self.recipeToEdit = None
        else:
            recipe = self.recipesList[mi.row()]
            self.recipeToEdit = mi.row()

            #Yleisien tietojen populoiminen
            self.recipeName.setText(recipe.getName())
            self.recipeTime.setText(recipe.getTimeGUI())
            self.recipeOutcomeSize.setText(recipe.getOutcomeSizeGUI())
            self.recipeOutcomeUnit.setText(recipe.getOutcomeUnit())
            
            #Muokkauskenttien nollaus
            self.clearRecipeEditLineEdits()
            
            #Aputaulujen populointi
            self.populateRecipesIngredientsTable()
            self.populateRecipesInstructionsTable()
            
    def populateRecipesIngredientEditFields(self,mi):
        ''' Tämä metodi populoi reseptinäkymällä olevat raaka-aine tekstikentät, joilla voi muokata reseptin raaka-aineen tietoja.
        Tätä metodia kutsutaan, kun reseptin raaka-ainelistaus taulua klikataan.
        
        Rivin indeksi tallennetaan self.recipeIngredientToEdit muuttujaan, jotta muutoksia tallennettaessa tiedetään
        mitä raaka-ainetta täytyy muokata.
        
        Args:
            :mi: mi muuttuja/olio, joka sisältää klikatun rivin ja kolumnin indeksin.
        ''' 
        
        ingredients = self.recipesList[self.recipeToEdit].getIngredients()
        if mi.row() >= len(ingredients):
            QMessageBox.warning(self, "Riviä ei voitu valita", "Päivitä listaus!", QMessageBox.Ok, QMessageBox.Ok)
            self.recipeIngredientToEdit = None
        else:
            ingredient = ingredients[mi.row()]
            self.recipeIngredientName.setText(ingredient.getName())
            self.recipeIngredientQuantity.setText(str(ingredient.getQuantityStr()))
            self.recipeIngredientUnit.setText(ingredient.getUnit())
            self.recipeIngredientToEdit = mi.row()        
       
    def populateRecipesInstructionsEditFields(self, mi):
        ''' Tämä metodi populoi reseptinäkymällä olen ohje tekstikentät, joilla voi muokata reseptin ohjetta.
        Tätä metodia kutsutaan, kun reseptin ohjelistaus taulua klikataan.
        
        Rivin indeksi tallennetaan self.recipeInstructionToEdit muuttujaan, jotta muutoksia tallennettaessa tiedetään
        mitä raaka-ainetta täytyy muokata.
        
        Args:
            :mi: mi muuttuja/olio, joka sisältää klikatun rivin ja kolumnin indeksin.
        ''' 
        instructions = self.recipesList[self.recipeToEdit].getInstructions()
        if mi.row() >= len(instructions):
            QMessageBox.warning(self, "Riviä ei voitu valita", "Päivitä listaus!", QMessageBox.Ok, QMessageBox.Ok)
            self.recipeInstructionToEdit = None
        else:
            instruction = instructions[mi.row()]
            self.recipeInstruction.setPlainText(instruction)        
            self.recipeInstructionToEdit = mi.row()   
                 
    def clearRecipeEditLineEdits(self):
        ''' Tämä metodi tyhjentää reseptin raaka-aine sekä ohjeen tekstikentät.
        Tätä metodia kutsutaan, kun reseptilistaus taulua klikataan, jotta kyseisissä tekstikentissä ei "vanhoja" tietoja.
        '''
        
        self.recipeIngredientToEdit = None
        self.recipeInstructionToEdit = None
        
        self.recipeInstruction.clear()
        
        self.recipeIngredientName.clear()
        self.recipeIngredientQuantity.clear()
        self.recipeIngredientUnit.clear()    
        
    def showCreateNewRecipeDialog(self):
        ''' Tämä metodi luo uuden QDialog widgetin, jossa voi täyttää uuden reseptin tietoja. Dialogin
        graafinen ulkoasu on luotu QT Designerilla ja on tallennettuna moduuliin GUIrecipeDialog.
        
        Jos dialogissa painetaan "OK" painiketta, kutsutaan metodia self.saveNewRecipe(), joka annetut tiedot
        ja tallentaa reseptin.
        '''
        self.dialog = QDialog()
        self.recipeDialog = Ui_Dialog()
        self.recipeDialog.setupUi(self.dialog)   
        self.initDialogLineEdits()     
        if self.dialog.exec_():
            self.saveNewRecipe()
        else:
            self.statusBar().showMessage("Tallennus keskeytetty")     
        
    def addNewRecipeInstruction(self):
        ''' Tämä metodi tallentaa reseptinäkymällä ohjetekstikentässä olevan tekstin uudeksi ohjeeksi reseptille. 
        Oikean reseptin löytymiseksi hyödynnetään self.recipeToEdit muuttujaa.
        
        Tallennuksen jälkeen metodi populoi uudelleen reseptin ohjelistaus taulun.
        '''
        
        try:
            recipe = self.recipesList[self.recipeToEdit]
            recipe.addInstruction(self.recipeInstruction.toPlainText())
            self.clearRecipeEditLineEdits()
            self.populateRecipesInstructionsTable()
            self.statusBar().showMessage("Ohje lisätty")
        except SetAttributeError as e:
            QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)


    
    def addNewRecipeIngredient(self):
        ''' Tämä metodi tarkastaa ja tallentaa reseptinäkymällä raaka-aine tekstikentissä olevat tekstit 
        uudeksi raaka-aineeksi reseptille. 
        Oikean reseptin löytymiseksi hyödynnetään self.recipeToEdit muuttujaa.
        
        Tallennuksen jälkeen metodi populoi uudelleen reseptin raaka-ainelistaus taulun.
        '''
        
        if self.recipeIngredientName.hasAcceptableInput() and self.recipeIngredientQuantity.hasAcceptableInput() and self.recipeIngredientUnit.hasAcceptableInput():
            try:
                recipe = self.recipesList[self.recipeToEdit]
                ingredient = IngredientContainer()
                ingredient.setIngredient(self.recipeIngredientName.text(),self.ingredientsList)
                ingredient.setQuantity(self.recipeIngredientQuantity.text())
                ingredient.setUnit(self.recipeIngredientUnit.text())
                recipe.addIngredientContainer(ingredient)
                self.populateRecipesIngredientsTable()
                self.statusBar().showMessage("Raaka-aine lisätty")
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)

    def deleteRecipeIngredient(self):
        ''' Tämä metodi poistaa valitun reseptin valitun raaka-aineen.
        
        Metodia kutsutaan painamalla poista painiketta. Oikea resepti ja raaka-aine selviää 
        muuttujista self.recipeToEdit ja self.recipeIngredientToEdit
        '''
        
        if self.recipeIngredientToEdit is not None and self.recipeToEdit is not None:
            try:
                recipe = self.recipesList[self.recipeToEdit]
                recipe.deleteIngredient(self.recipeIngredientToEdit)
                self.populateRecipesIngredientsTable()
                self.statusBar().showMessage("Raaka-aine poistettu")
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)

        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Päivitä listaus ja valitse resepti sekä raaka-aine uudelleen!", QMessageBox.Ok, QMessageBox.Ok)
    
    def deleteRecipeInstruction(self):
        ''' Tämä metodi poistaa valitun reseptin valitun ohjeen.
        
        Metodia kutsutaan painamalla poista painiketta. Oikea resepti ja ohje selviää 
        muuttujista self.recipeToEdit ja self.recipeInstructionToEdit
        '''
        
        if self.recipeInstructionToEdit is not None and self.recipeToEdit is not None:
            try:
                recipe = self.recipesList[self.recipeToEdit]
                recipe.deleteInstruction(self.recipeInstructionToEdit)
                self.populateRecipesInstructionsTable()
                self.statusBar().showMessage("Ohje poistettu")
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)

        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Päivitä listaus ja valitse resepti sekä ohje uudelleen!", QMessageBox.Ok, QMessageBox.Ok)


    def checkStateChanged(self,state):
        ''' Tämä metodi pitää huolen, ettei hakunäkymällä olevat "Puuttuu N" ja "Löytyy N" checkboksit ole valittuna samaan aikaan,
        koska se ei ole järin järkevä hakuvaihtoehto. 
        
        Tätä metodia kutsutaan vaihtamalla jomman kumman checkboksin tilaa.
        '''
        # Jos rasti otettiin pois, niin toisen tilaa ei tarvitse vaihtaa
        if state != Qt.Checked:
            pass
        elif self.sender() == self.checkFoundN:
            self.checkMissingN.setChecked(False)
        elif self.sender() == self.checkMissingN:
            self.checkFoundN.setChecked(False)
            

    def saveNewRecipe(self):
        ''' Tämä metodi tarkastaa uusi resepti -dialogissa annetut tiedot ja valideja, niin luo uuden reseptin näillä tiedoilla
        ja lisää sen reseptilistaan. Tämän jälkeen reseptilistaus taulu populoidaan uudelleen.
        
        '''
        if self.recipeDialog.dialogName.hasAcceptableInput() and self.recipeDialog.dialogInstruction.hasAcceptableInput() and self.recipeDialog.dialogIngredient.hasAcceptableInput() and self.recipeDialog.dialogOutcomeSize.hasAcceptableInput() and self.recipeDialog.dialogOutcomeUnit.hasAcceptableInput() and self.recipeDialog.DialogQuantity.hasAcceptableInput() and self.recipeDialog.dialogTime.hasAcceptableInput() and self.recipeDialog.dialogUnit.hasAcceptableInput():
            recipe = Recipe()
            try:
                today = datetime.date.today()
                recipe.setName(self.recipeDialog.dialogName.text())
                recipe.setDate(today.strftime("%d.%m.%Y"))
                recipe.setTime(self.recipeDialog.dialogTime.text())
                recipe.addInstruction(self.recipeDialog.dialogInstruction.text())
                recipe.setOutcomeSize(self.recipeDialog.dialogOutcomeSize.text())
                recipe.setOutcomeUnit(self.recipeDialog.dialogOutcomeUnit.text())
                
                ingredient = IngredientContainer()
                ingredient.setIngredient(self.recipeDialog.dialogIngredient.text(), self.ingredientsList)
                ingredient.setQuantity(self.recipeDialog.DialogQuantity.text())
                ingredient.setUnit(self.recipeDialog.dialogUnit.text())
                recipe.addIngredient(ingredient)
                self.recaddIngredientContainernd(recipe)
                self.populateRecipesTable()
                self.statusBar().showMessage("Reseptin tallennus onnistui")
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Kaikissa kentissä ei syötettä", QMessageBox.Ok, QMessageBox.Ok)

                 
    def saveRecipesEdit(self):
        ''' Tämä metodi tarkistaa reseptin perustietojen tekstikenttien arvot, jonka jälkeen muutokset tallennetaan reseptiin.
        
        Oikea resepti löydetään self.recipeToEdit muuttujan avulla.
        '''
        
        if self.recipeName.hasAcceptableInput() and self.recipeTime.hasAcceptableInput() and self.recipeOutcomeSize.hasAcceptableInput() and self.recipeOutcomeUnit.hasAcceptableInput() and self.recipeToEdit is not None:
            try:
                recipe = self.recipesList[self.recipeToEdit]
                recipe.setName(self.recipeName.text())
                recipe.setTime(self.recipeTime.text())
                recipe.setOutcomeSize(self.recipeOutcomeSize.text())
                recipe.setOutcomeUnit(self.recipeOutcomeUnit.text())
                self.statusBar().showMessage("Reseptin perustiedot tallennettu")
                self.populateRecipesTable()
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)
            
    def saveRecipesIngredientEdit(self):
        ''' Tämä metodi tarkistaa reseptin raaka-aineen tekstikenttien arvot, jonka jälkeen muutokset tallennetaan reseptiin.
        
        Oikea resepti sekä raaka-aine löydetään self.recipeToEdit ja self.recipeIngredientToEdit muuttujien avulla.
        '''
        
        if self.recipeIngredientQuantity.hasAcceptableInput() and self.recipeIngredientUnit.hasAcceptableInput() and self.recipeToEdit is not None and self.recipeIngredientToEdit is not None:
            try:
                ingredient = self.recipesList[self.recipeToEdit].getIngredients()[self.recipeIngredientToEdit]
                ingredient.setQuantity(self.recipeIngredientQuantity.text())
                ingredient.setUnit(self.recipeIngredientUnit.text())
                self.statusBar().showMessage("Reseptin raaka-aine tallennettu")
                self.populateRecipesIngredientsTable()
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)
            
    def saveRecipesInstructionsEdit(self):
        ''' Tämä metodi tallentaa annetun ohjetekstin reseptille.
        
        Oikea resepti sekä ohje löydetään self.recipeToEdit ja self.recipeInstructionToEdit muuttujien avulla.
        '''        
        if  self.recipeToEdit is not None and self.recipeInstructionToEdit is not None:
            try:
                instructions = self.recipesList[self.recipeToEdit].getInstructions()
                instructions[self.recipeInstructionToEdit] = self.recipeInstruction.toPlainText()
                self.statusBar().showMessage("Ohje tallennettu")
                self.populateRecipesInstructionsTable()
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)
            
            
    def saveStorageEdit(self):
        ''' Tämä metodi tarkistaa varastossa olevan raaka-aineen perustietojen tekstikenttien arvot, jonka jälkeen muutokset tallennetaan raaka-aineeseen.
        
        Oikea raaka-aine löydetään self.storageToEdit muuttujan avulla.
        '''
        if self.storageQuantity.hasAcceptableInput() and self.storageUnit.hasAcceptableInput() and self.storageToEdit is not None:
            try:
                storage = self.storageList[self.storageToEdit]
                storage.setQuantity(self.storageQuantity.text())
                storage.setUnit(self.storageUnit.text())
                self.statusBar().showMessage("Varastotuote tallennettu")
                self.populateStorageTable()
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)
    
    def saveIngredientsEdit(self):
        ''' Tämä metodi tarkistaa raaka-aineen perustietojen tekstikenttien arvot, jonka jälkeen muutokset tallennetaan raaka-aineeseen.
        
        Oikea raaka-aine löydetään self.ingredientToEdit muuttujan avulla.
        '''
        if self.ingredientName.hasAcceptableInput() and self.ingredientDensity.hasAcceptableInput() and self.ingredientToEdit is not None:
            try:
                ingredient = self.ingredientsList[self.ingredientToEdit]
                ingredient.setName(self.ingredientName.text())
                ingredient.setDensity(self.ingredientDensity.text())
                if self.ingredientAllergens.isModified():
                    ingredient.removeAllergens()
                    for i in self.ingredientAllergens.text().strip().split(","):
                        ingredient.addAllergen(i)
                if self.ingredientRecipe.isModified():
                    recipe = self.ingredientRecipe.text()
                    ingredient.removeRecipe()
                    ingredient.setRecipe(recipe)
                    ingredient.loadRecipe(self.recipesList)
                self.statusBar().showMessage("Raaka-aine tallennettu")
                self.populateIngredientsTable()
            except SetAttributeError as e:
                QMessageBox.warning(self, "Virhe tallentaessa", str(e), QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.warning(self, "Virhe tallentaessa", "Virheellinen syöte!", QMessageBox.Ok, QMessageBox.Ok)
    
    
    def openFileUTF8(self,file):
        ''' Tämä metodi avaa halutun tiedoston UTF-8 enkoodauksella ja palauttaa sen tiedostokahvan.
        
        Args:
            :file: tiedoston polku
        
        Returns:
            :Onnistuessa: tiedostokahva avattuun tiedostoon
            :Epäonnistuessa: False
        '''
        
        try:
            fileIO = codecs.open(file, "r", "utf-8")
            return fileIO
        except IOError:
            print("Tiedoston",file,"avaaminen ei onnistu.") 
            return False
    
    def loadFromFileToList(self):
        ''' Tämä metodi päättelee kutsujan (self.sender()) perusteella mikä tiedosto tulee ladata uudelleen ja myöskin lataa sen.
        
        Jos self.sender() on None, niin ladataan kaikki tiedostot. Muulloin kutsuja on esim. self.buttonLoadRecipes, jolloin ladataan
        reseptit tiedostosta.
        '''
        sender = self.sender()
        try:        
            if sender is None or sender is self.buttonLoadAll:
                self.ingredientsList = []
                fileIO = self.openFileUTF8(self.ingredientsFile)
                self.ingredientsList, self.ingredientsSuccess, self.ingredientsError = self.IO.loadIngredients(fileIO)
                
                self.recipesList = []
                fileIO = self.openFileUTF8(self.recipesFile)
                self.recipesList, self.recipesSuccess, self.recipesError = self.IO.loadRecipes(fileIO, self.ingredientsList)
                
                self.storageList = []
                fileIO = self.openFileUTF8(self.storageFile)
                self.storageList, self.storageSuccess, self.storageError = self.IO.loadStorage(fileIO, self.ingredientsList)
                self.statusBar().showMessage("Kaikki luettu sisään")
                
                self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)
            elif sender is self.buttonLoadRecipes:
                self.recipesList = []
                fileIO = self.openFileUTF8(self.recipesFile)
                self.recipesList, self.recipesSuccess, self.recipesError = self.IO.loadRecipes(fileIO, self.ingredientsList)
                self.statusBar().showMessage("Reseptit luettu sisään")

            elif sender is self.buttonLoadStorage:
                self.storageList = []
                fileIO = self.openFileUTF8(self.storageFile)
                self.storageList, self.storageSuccess, self.storageError = self.IO.loadStorage(fileIO, self.ingredientsList)
                self.statusBar().showMessage("Varastotilanne luettu sisään")

            elif sender is self.buttonLoadIngredients:
                self.ingredientsList = []
                fileIO = self.openFileUTF8(self.ingredientsFile)
                self.ingredientsList, self.ingredientsSuccess, self.ingredientsError = self.IO.loadIngredients(fileIO)
                self.statusBar().showMessage("Raaka-aineet luettu sisään")
                self.IO.loadRecipesForIngredients(self.ingredientsList, self.recipesList)

            else:
                print("Tuntematon tyyppi")
                return -1
        except CorruptedFileError as e:
            QMessageBox.warning(self, "Virhe sisäänluvussa", str(e), QMessageBox.Ok, QMessageBox.Ok)    
        
        fileIO.close()
        
    def saveToFile(self):
        ''' Tämä metodi päättelee kutsujan (self.sender()) perusteella mikä tiedosto tulee tallentaa ja myöskin tallentaa sen.
        
        Jos self.sender() on self.buttonSaveAll, niin ladataan kaikki tiedostot. Muulloin kutsuja on esim. self.buttonSaveRecipes, jolloin 
        tallennetaan reseptit tiedostoon.
        '''
        sender = self.sender()
        if sender is self.buttonSaveAll:
            self.IO.saveRecipes(self.recipesFile, self.recipesList)
            self.IO.saveIngredients(self.ingredientsFile, self.ingredientsList)
            self.IO.saveStorage(self.storageFile, self.storageList)
            self.statusBar().showMessage("Kaikki tallennettu tiedostoihin")
        elif sender is self.buttonSaveRecipes:
            self.IO.saveRecipes(self.recipesFile, self.recipesList)
            self.statusBar().showMessage("Reseptit tallennettu tiedostoihin")
        elif sender is self.buttonSaveIngredients:
            self.IO.saveIngredients(self.ingredientsFile, self.ingredientsList)
            self.statusBar().showMessage("Raaka-aineet tallennettu tiedostoihin")
        elif sender is self.buttonSaveStorage:
            self.IO.saveStorage(self.storageFile, self.storageList)
            self.statusBar().showMessage("Varastotilanne tallennettu tiedostoihin")
        else:
            print("Kuka kutsuu SaveToFile?")
    

    def getIngredientsInDataListForTable(self, ingredientList):
        ''' Muodostaa annetujen raaka-aineiden tiedoista listojen listan, jotka on helppo populoida QTabletWidget tauluun.
        '''
        
        names = []
        allergens = []
        recipes = []
        densities = []
        headers = ['Nimi', 'Allergeenit', 'Resepti', 'Tiheys']
        
        for ingredient in ingredientList:
            names.append(ingredient.getName())
            allergens.append(ingredient.getAllergensGUI())
            recipes.append(ingredient.getRecipeGUI())
            densities.append(ingredient.getDensityGUI())
        
        return [headers,names,allergens,recipes,densities]
    
    def getIngredientContainersInDataListForTable(self, ingredientContainerList):
        ''' Muodostaa annetujen raaka-aineiden(container) tiedoista listojen listan, jotka on helppo populoida QTabletWidget tauluun.
        '''
        names = []
        quantities = []
        units = []
        headers = ['Nimi', 'Määrä', 'Yksikkö']
        
        for ingredientContainer in ingredientContainerList:
            names.append(ingredientContainer.getName())
            quantities.append(ingredientContainer.getQuantityStr())
            units.append(ingredientContainer.getUnit())
        
        return [headers,names,quantities,units]
    
    def getRecipesInDataListForTable(self, recipeList):
        ''' Muodostaa annetujen reseptien tiedoista listojen listan, jotka on helppo populoida QTabletWidget tauluun.
        '''
        
        names = []
        times = []
        outcomes = []
        allergens = []
        headers = ['Nimi', 'Aika', 'Lopputulos', 'Allergeenit']
        
        for recipe in recipeList:
            names.append(recipe.getName())
            times.append(recipe.getTimeStr())
            outcomes.append(recipe.getOutcomeStr())
            allergens.append(recipe.getAllergensDistinctGUI())
        
        return [headers,names,times,outcomes, allergens]
コード例 #25
0
ファイル: trab1.py プロジェクト: igorventorim/UFES
#!/usr/bin/env python
# -'- coding: utf-8 -'-

from Catalogo import Catalogo
from Livro import Livro
from IO import IO

livros = Catalogo()
IO.readCatalogo("catalogo.txt",livros)
IO.readUpdate("atual.txt",livros)
IO.writeOutput(livros)
IO.writeCatalogo("catalogo.txt",livros)
コード例 #26
0
ファイル: game.py プロジェクト: initrl/MinecraftRL
class Game:
    def __init__(self):
        self.cons = IO()
        
        self.world = World()

        self.player = self.world.player

        self.player.update()
        self.world.updateAllC()
     
        self.colors = [libtcod.red, libtcod.green, libtcod.blue, libtcod.white,
                  libtcod.gray, libtcod.flame, libtcod.light_green, libtcod.yellow,
                  libtcod.gold, libtcod.darker_yellow]

    def mainloop(self):
        while 1:
            self.cons.clear()
            for x in range(self.player.x - SW,self.player.x + SW):
                for y in range(self.player.y - SH,self.player.y + SH):
                    char = self.world.char(x, y)
                    color = self.world.get(x,y).color
                    color2 = libtcod.dark_gray
                    color3 = libtcod.color_lerp(color,color2,
                        (((x - self.player.x)**2) + ((y-self.player.y)**2)) / 2500.0)
                    color = libtcod.color_lerp(color3,libtcod.white,0.1)
                    libtcod.console_put_char(self.cons.console,
                                 (W/2 - self.player.x) + x,
                                 (H/2 - self.player.y) + y,
                                 char,
                                 libtcod.BKGND_DEFAULT)
                    libtcod.console_set_char_foreground(self.cons.console,
                                (W/2 - self.player.x) + x,
                                (H/2 - self.player.y) + y,
                                color)

            self.cons.prints(W/2,H/2,"@",self.player.color,False)

            x = W/2 - (len(self.colors) * 2)
            for i in range(len(self.colors)):
                color = self.colors[i]
                if i == 9:
                    if i == self.player.ccolor:
                        self.cons.printex(x, H - 4, ("%c+%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                    else:
                        self.cons.printex(x, H - 2, ("%c+%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                    self.cons.printex(x, H - 3, ("%c+%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                else:
                    if i == self.player.ccolor:
                        self.cons.printex(x, H - 4, ("%c#%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                    else:
                        self.cons.printex(x, H - 2, ("%c#%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                    self.cons.printex(x, H - 3, ("%c#%c" % (libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) * 2, color, False)
                x += 4
            
            self.cons.printex(0, H - 1, "%c%s%c" % (libtcod.COLCTRL_1,TITLE +
                    " (" + DAY + ")",libtcod.COLCTRL_STOP),libtcod.flame, True)
            
            key = self.cons.key()
        
            if key.c == ord('q'):
                break
            elif self.keyparse(key):
                self.player.move(self.keyparse(key),self.movecheck)
            elif key.c == ord('x'):
                key = libtcod.console_wait_for_keypress(True)
                if self.keyparse(key):
                    yx2 = self.keyparse(key)[0] + self.player.x
                    yy2 = self.keyparse(key)[1] + self.player.y
                    if self.world.get(yx2,yy2).walkable and self.world.get(yx2,yy2).chr != "~":
                        if self.player.ccolor == 9:
                            self.world.setCell(yx2,yy2,Door())
                        else:
                            self.world.setCell(yx2,yy2,Block(self.colors[self.player.ccolor]))
                        self.world.updateC(yx2, yy2)
                    continue

            elif key.c == ord('z'):
                key = libtcod.console_wait_for_keypress(True)
                if self.keyparse(key):
                    yx2 = self.keyparse(key)[0] + self.player.x
                    yy2 = self.keyparse(key)[1] + self.player.y
                    if self.world.get(yx2,yy2).diggable and not self.world.get(yx2,yy2).walkable:
                        self.world.setCell(yx2,yy2,Dirt())
                        self.world.updateC(yx2, yy2)
                    continue

            elif key.c == ord('c'):
                key = libtcod.console_wait_for_keypress(True)
                if self.keyparse(key):
                    yx2 = self.keyparse(key)[0] + self.player.x
                    yy2 = self.keyparse(key)[1] + self.player.y
                    if self.world.get(yx2,yy2).chr == "+" or           \
                     self.world.get(yx2,yy2).chr == "-":
                        self.world.get(yx2,yy2).toggle()
                        self.world.updateC(yx2, yy2)
                    continue
            
    def movecheck(self,x,y):
        if self.world.get(x,y).chr == "+":
            self.world.get(x,y).toggle()
            self.world.updateC(x, y)
            return False
        return self.world.get(x,y).walkable

    def keyparse(self,key):
        y = x = 0
        if key.c == ord('8') or key.c == ord('k'):
            y = -1
        elif key.c == ord('4') or key.c == ord('h'):
            x = -1
        elif key.c == ord('6') or key.c == ord('l'):
            x = 1
        elif key.c == ord('2') or key.c == ord('j'):
            y = 1
    
        elif key.c == ord('7') or key.c == ord('y'):
            y = -1
            x = -1
        elif key.c == ord('9') or key.c == ord('u'):
            y = -1
            x = 1
        elif key.c == ord('1') or key.c == ord('b'):
            y = 1
            x = -1
        elif key.c == ord('3') or key.c == ord('n'):
            y = 1
            x = 1
        else:
            return False
        return x, y