merge two xml files xslt 3 based on the value of common id element - xslt-3.0

<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<id>$5</id>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<id>7</id>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<id>8</id>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<id>4</id>
<description>Thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<id>6</id>
<description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
</food>
</breakfast_menu>
i have tried to achieve the task with the help of xsl:merge. In my trials i have to specific define in xsl which elements to retrieve. How would you suggest one with the help of xslt-3, can retrieve all elements from the second xml file, minus the id element, which already exists in XML file A, and is used as the match criteria for merging the two xml files into one?
second xml file:
<CATALOG>
<PLANT>
<COMMON>Butterfly Weed</COMMON>
<BOTANICAL>Asclepias tuberosa</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Sunny</LIGHT>
<id>2</id>
<AVAILABILITY>063099</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Primrose</COMMON>
<BOTANICAL>Oenothera</BOTANICAL>
<ZONE>3 - 5</ZONE>
<LIGHT>Sunny</LIGHT>
<id>6</id>
<AVAILABILITY>013099</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Gentian</COMMON>
<BOTANICAL>Gentiana</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Sun or Shade</LIGHT>
<id>17</id>
<AVAILABILITY>051899</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Blue Gentian</COMMON>
<BOTANICAL>Gentiana</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Sun or Shade</LIGHT>
<id>18</id>
<AVAILABILITY>050299</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Jacob's Ladder</COMMON>
<BOTANICAL>Polemonium caeruleum</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Shade</LIGHT>
<id>9</id>
<AVAILABILITY>022199</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Greek Valerian</COMMON>
<BOTANICAL>Polemonium caeruleum</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Shade</LIGHT>
<id>4</id>
<AVAILABILITY>071499</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>California Poppy</COMMON>
<BOTANICAL>Eschscholzia californica</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Sun</LIGHT>
<id>7</id>
<AVAILABILITY>032799</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Shooting Star</COMMON>
<BOTANICAL>Dodecatheon</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<id>8</id>
<AVAILABILITY>051399</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Snakeroot</COMMON>
<BOTANICAL>Cimicifuga</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Shade</LIGHT>
<id>5</id>
<AVAILABILITY>071199</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Cardinal Flower</COMMON>
<BOTANICAL>Lobelia cardinalis</BOTANICAL>
<ZONE>2</ZONE>
<LIGHT>Shade</LIGHT>
<id>3</id>
<AVAILABILITY>022299</AVAILABILITY>
</PLANT>
</CATALOG>
Desired output:
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<id>5</id>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
<COMMON>Snakeroot</COMMON>
<BOTANICAL>Cimicifuga</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Shade</LIGHT>
<AVAILABILITY>071199</AVAILABILITY>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<id>7</id>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
<COMMON>California Poppy</COMMON>
<BOTANICAL>Eschscholzia californica</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Sun</LIGHT>
<AVAILABILITY>032799</AVAILABILITY>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<id>8</id>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
<COMMON>Shooting Star</COMMON>
<BOTANICAL>Dodecatheon</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<AVAILABILITY>051399</AVAILABILITY>
</food>
<food>
<name>French Toast</name>
<id>4</id>
<description>Thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
<COMMON>Greek Valerian</COMMON>
<BOTANICAL>Polemonium caeruleum</BOTANICAL>
<ZONE>Annual</ZONE>
<LIGHT>Shade</LIGHT>
<AVAILABILITY>071499</AVAILABILITY>
</food>
<food>
<name>Homestyle Breakfast</name>
<id>6</id>
<description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
<COMMON>Primrose</COMMON>
<BOTANICAL>Oenothera</BOTANICAL>
<ZONE>3 - 5</ZONE>
<LIGHT>Sunny</LIGHT>
<AVAILABILITY>013099</AVAILABILITY>
</food>
</breakfast_menu>
my approach part of it to give you an idea:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:param name="doc-A" select="doc('fileB.xml')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:merge>
<xsl:merge-source sort-before-merge="yes" for-each-item="." select="food">
<xsl:merge-key select="id"/>
</xsl:merge-source>
<xsl:merge-source sort-before-merge="yes" for-each-item="$doc-A" select="//PLANT">
<xsl:merge-key select="id"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:copy>
<xsl:copy-of select="current-merge-group('A')/*, current-merge-group('B')/(* except id)"/>
</xsl:copy>
</xsl:merge-action>
</xsl:merge>
</xsl:copy>
</xsl:template>
<xsl:param name="merge-data"/>
<xsl:copy>{.}{$merge-data}</xsl:copy>
</xsl:template>
<xsl:param name="merge-data"/>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>

I would use e.g.
<xsl:merge-action>
<xsl:copy>
<xsl:copy-of select="current-merge-group('A')/*, current-merge-group('B')/(* except id)"/>
</xsl:copy>
</xsl:merge-action>
This obviously assumes you are naming your merge sources, which you had done initially in your code, you edited that out after my answer, go figure.
Anyway, it seems you also want to ignore data from the second file so the merge action needs to check for a merge source from A:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:merge>
<xsl:merge-source name="A" sort-before-merge="yes" for-each-item="." select="food">
<xsl:merge-key select="id"/>
</xsl:merge-source>
<xsl:merge-source name="B" sort-before-merge="yes" for-each-item="$doc-A" select="//PLANT">
<xsl:merge-key select="id"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:if test="current-merge-group('A')">
<xsl:copy>
<xsl:copy-of select="current-merge-group('A')/*, current-merge-group('B')/(* except id)"/>
</xsl:copy>
</xsl:if>
</xsl:merge-action>
</xsl:merge>
</xsl:copy>
</xsl:template>
<xsl:param name="doc-A" select="doc('fileB.xml')"/>
</xsl:stylesheet>
In the end, given that xsl:merge needs to order input sources to work and given that you desired output doesn't seem to be ordered based on the id, I would think that a key based solution might work better:
<xsl:param name="ref" match="PLANT" use="id"/>
and then <xsl:mode on-no-match="shallow-copy"/> plus
<xsl:template match="food[key('ref', id, doc('fileB.xml'))]">
<xsl:copy>
<xsl:apply-templates select="*, key('ref', id, doc('fileB.xml'))/(* except id)"/>
</xsl:copy>
</xsl:template>

Related

Python3 list in function with Pyqt5 missing something

Hi I am trying to move the MIT 6001 python3 assignement
number 2 into PyQt5.
Here my files:
main.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QDesktopWidget
import hangman005
WORDLIST_FILENAME = "words.txt_short"
wordlist = hangman005.load_words(WORDLIST_FILENAME)
def main():
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class MainMenu(QtWidgets.QMainWindow):
def __init__(self):
super(MainMenu, self).__init__()
uic.loadUi('main_window2.ui', self)
self.centro = center(self)
self.centro
self.show()
self.error_label.hide()
self.groupBox.hide()
self.word_to_guess.hide()
self.available_guess.hide()
self.vowels=('a','e','i','o','u')
self.newgame_button.clicked.connect(self.start2)
def closeEvent(self, event): #Your desired functionality here
close = QtWidgets.QMessageBox.question(self,
"QUIT",
"Are you sure want to stop process?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if close == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def start2(self):
self.error_label.hide()
self.newgame_button.hide()
self.groupBox.show()
self.word_to_guess.show()
self.available_guess.show()
self.letters_guessed=[]
self.max_guesses = 6
self.secret_word = hangman005.choose_word(wordlist)
self.secret_word_lenght=len(self.secret_word)
self.secret_word=hangman005.splitt(self.secret_word)
self.secret_word_print=('_ '*self.secret_word_lenght )
self.word_to_guess.setText(self.secret_word_print )
self.available_guess.setText(str(self.max_guesses) )
self.letters=hangman005.splitt('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
for i in self.letters:
getattr(self, i).setEnabled(True)
self.hangman_pyqt5()
def hangman_pyqt5(self):
print(self.letters )
for f in self.letters:
print('lllllllllllllll : ' ,f)
getattr(self, f).clicked.connect(lambda pippo, j=f: self.printo(j))
def printo(self, i):
print('oooooooooooooooooooooo :', i.lower())
getattr(self, i).setEnabled(False)
i=i.lower()
self.word_to_guess.setText((' '.join(hangman005.get_guessed_word(self.secret_word, self.letters_guessed))).upper())
self.available_guess.setText(str(self.max_guesses) )
print(self.secret_word*5 )
if i not in hangman005.get_available_letters(self.letters_guessed):
print('You can only choose in' , ' '.join(hangman005.get_available_letters(self.letters_guessed)))
return
elif i in hangman005.get_available_letters(self.letters_guessed):
self.letters_guessed.append(i)
print(' a che punto sei : ' , ' '.join(hangman005.get_guessed_word(self.secret_word, self.letters_guessed)))
self.word_to_guess.setText((' '.join(hangman005.get_guessed_word(self.secret_word, self.letters_guessed)).upper()))
self.available_guess.setText(str(self.max_guesses) )
if i in self.secret_word:
print('GOOD !!!!!!!!!!!!!')
print('\nyou still have ' , self.max_guesses , ' guesses be carefull choosing')
else:
print('ERRORE !!!!!!!!!!!!!!!!!!!!!!')
if i in self.vowels:
self.max_guesses -= 2
self.available_guess.setText(str(self.max_guesses) )
else:
self.max_guesses -= 1
self.available_guess.setText(str(self.max_guesses) )
print('\nnow you have only' , self.max_guesses , ' guesses be carefull choosing')
if hangman005.is_word_guessed(self.secret_word, self.letters_guessed) == True:
print('\nHAI VINTO !!!!!!!!!!!!!!!!!!!!!!')
total_score= self.max_guesses * len(list(set(self.secret_word)))
print('\nil tuo punteggio è : ' , total_score)
return
if self.max_guesses <= 0:
print('\nHAI PERSO STUPIDA CAPRA !!!!!!!!!!!!!!!!!!!!!!')
print('\n\n\n secret_word : ' , self.secret_word )
print('\nla parola era : ' , ''.join(self.secret_word), ' you moron !!')
self.error_label.show()
# self.newgame_button.show()
self.groupBox.hide()
self.word_to_guess.setText((''.join(self.secret_word)).upper())
self.available_guess.hide()
# self.letters_guessed.clear()
# self.letters_guessed=[]
self.newgame_button.show()
return
app = QtWidgets.QApplication(sys.argv)
# sshFile="coffee.qss"
# with open(sshFile,"r") as fh:
# app.setStyleSheet(fh.read())
app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
window=MainMenu()
window.show()
app.exec_()
#all_objects = muppy.get_objects()
#sum1 = summary.summarize(all_objects)# Prints out a summary of the large objects
#summary.print_(sum1)# Get references to certain types of objects such as dataframe
if __name__ == '__main__':
main()
hangman005.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random
import string
def load_words(WORDLIST_FILENAME):
print("Loading word list from file...")
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r')
# line: string
line = inFile.readline()
# wordlist: list of strings
wordlist = line.split()
print(" ", len(wordlist), "words loaded.")
return wordlist
def choose_word(wordlist):
return random.choice(wordlist)
def splitt(word):
return [char for char in word]
def is_word_guessed(secret_word, letters_guessed):
prova =all(item in letters_guessed for item in secret_word )
print(' prova : ' , prova )
return prova
def get_guessed_word(secret_word, letters_guessed):
print('\n\nsecret_word_split' , secret_word)
print('letters_guessed', letters_guessed )
results=[]
for val in range(0,len(secret_word)):
if secret_word[val] in letters_guessed:
results.append(secret_word[val])
else:
results.append('_')
print('\nresults : ' , ' '.join(results ))
return results
def get_available_letters(letters_guessed):
entire_letters='abcdefghijklmnopqrstuvwxyz'
entire_letters_split=splitt(entire_letters)
entire_letters_split = [x for x in entire_letters_split if x not in letters_guessed]
return entire_letters_split
def hangman(secret_word):
letters_guessed=[]
max_guesses = 6
secret_word_lenght=len(secret_word)
secret_word=splitt(secret_word)
vowels=('a','e','i','o','u')
print('\nWelcome to HANGMAN ;-) ')
print('\nsecret_word_lenght : ' , secret_word_lenght )
print('\n'+' _ '*secret_word_lenght )
print('\nyou have ' , max_guesses , ' guesses be carefull choosing')
while True:
guess= input('\nmake your first choice : ' )
if guess not in get_available_letters(letters_guessed):
print('You can only choose in' , ' '.join(get_available_letters(letters_guessed)))
continue
if guess in get_available_letters(letters_guessed):
letters_guessed.append(guess)
# print('\nletters_guessed appended : ' , ' '.join(letters_guessed) )
# max_guesses -= 1
print(' a che punto sei : ' , ' '.join(get_guessed_word(secret_word, letters_guessed)))
# print('\nyou have ' , max_guesses , ' guesses be carefull choosing')
if guess in secret_word:
print('GOOD !!!!!!!!!!!!!')
print('\nyou still have ' , max_guesses , ' guesses be carefull choosing')
else:
print('ERRORE !!!!!!!!!!!!!!!!!!!!!!')
if guess in vowels:
max_guesses -= 2
else:
max_guesses -= 1
print('\nnow you have only' , max_guesses , ' guesses be carefull choosing')
if is_word_guessed(secret_word, letters_guessed) == True:
print('\nHAI VINTO !!!!!!!!!!!!!!!!!!!!!!')
total_score= max_guesses * len(list(set(secret_word)))
print('\nil tuo punteggio è : ' , total_score)
break
if max_guesses <= 0:
print('\nHAI PERSO STUPIDA CAPRA !!!!!!!!!!!!!!!!!!!!!!')
print('\nla parola era : ' , ''.join(secret_word), ' you moron !!')
break
def match_with_gaps(my_word, other_word):
if len(my_word) == len(other_word):
for val in range(0,len(my_word)):
if my_word[val] == '_':
# print('OK')
prova=True
elif my_word[val] != '_' and my_word[val]==other_word[val]:
# print('OK')
prova=True
else:
# print('KO')
prova=False
break
else:
# print('DIFFERENT LENGHT')
prova=False
return prova
def show_possible_matches(my_word):
x=0
y=0
for i in range(0,len(wordlist)):
other_word=splitt(wordlist[i])
if match_with_gaps(my_word, other_word):
print(wordlist[i], end = ' ')
x += 1
else:
y += 1
print('\nparole trovate : ' , x)
print('parole saltate : ' , y)
print('parole totali : ' , x+y)
print('lenght wordlist :' , len(wordlist))
return
end = ''
def hangman_with_hints(secret_word):
# secret_word_lenght=len(secret_word)
# print('secret_word_lenght : ' , secret_word_lenght )
letters_guessed=[]
max_guesses = 6
secret_word_lenght=len(secret_word)
secret_word=splitt(secret_word)
vowels=('a','e','i','o','u')
print('\nWelcome to HANGMAN ;-) ')
print('\nsecret_word_lenght : ' , secret_word_lenght )
print('\n use * for superhelp !!!! ')
print('\n'+' _ '*secret_word_lenght )
print('\nyou have ' , max_guesses , ' guesses be carefull choosing')
while True:
guess= input('\nmake your choice : ' )
if guess == '*' :
print('ATTENZIONE SUPER BONUS !!!')
my_word=(get_guessed_word(secret_word, letters_guessed))
show_possible_matches(my_word)
continue
if guess not in get_available_letters(letters_guessed):
print('You can only choose in' , ' '.join(get_available_letters(letters_guessed)))
continue
if guess in get_available_letters(letters_guessed):
letters_guessed.append(guess)
# print('\nletters_guessed appended : ' , ' '.join(letters_guessed) )
# max_guesses -= 1
print(' a che punto sei : ' , ' '.join(get_guessed_word(secret_word, letters_guessed)))
# print('\nyou have ' , max_guesses , ' guesses be carefull choosing')
if guess in secret_word:
print('GOOD !!!!!!!!!!!!!')
print('\nyou still have ' , max_guesses , ' guesses be carefull choosing')
else:
print('ERRORE !!!!!!!!!!!!!!!!!!!!!!')
if guess in vowels:
max_guesses -= 2
else:
max_guesses -= 1
print('\nnow you have only' , max_guesses , ' guesses be carefull choosing')
if is_word_guessed(secret_word, letters_guessed) == True:
print('\nHAI VINTO !!!!!!!!!!!!!!!!!!!!!!')
total_score= max_guesses * len(list(set(secret_word)))
print('\nil tuo punteggio è : ' , total_score)
break
if max_guesses <= 0:
print('\nHAI PERSO STUPIDA CAPRA !!!!!!!!!!!!!!!!!!!!!!')
print('\nla parola era : ' , ''.join(secret_word).upper(), ' you moron !!')
break
#if __name__ == "__main__":
# passui
# To test part 2, comment out the pass line above and
# uncomment the following two lines.
# secret_word = choose_word(wordlist)
# hangman(secret_word)
###############
# To test part 3 re-comment out the above lines and
# uncomment the following two lines.
# secret_word = choose_word(wordlist)
# hangman_with_hints(secret_word)
main_window2.ui :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>936</width>
<height>686</height>
</rect>
</property>
<property name="windowTitle">
<string>HANGMAN</string>
</property>
<property name="styleSheet">
<string notr="true">
</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="word_to_guess">
<property name="geometry">
<rect>
<x>270</x>
<y>30</y>
<width>341</width>
<height>91</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>word_to_guess</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>50</x>
<y>320</y>
<width>821</width>
<height>201</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #9de650;
}
QPushButton:hover{
background-color: green;
}
</string>
</property>
<property name="title">
<string/>
</property>
<widget class="QPushButton" name="A">
<property name="geometry">
<rect>
<x>30</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>A</string>
</property>
</widget>
<widget class="QPushButton" name="B">
<property name="geometry">
<rect>
<x>90</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>B</string>
</property>
</widget>
<widget class="QPushButton" name="C">
<property name="geometry">
<rect>
<x>150</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
<widget class="QPushButton" name="D">
<property name="geometry">
<rect>
<x>210</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>D</string>
</property>
</widget>
<widget class="QPushButton" name="E">
<property name="geometry">
<rect>
<x>270</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>E</string>
</property>
</widget>
<widget class="QPushButton" name="F">
<property name="geometry">
<rect>
<x>330</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>F</string>
</property>
</widget>
<widget class="QPushButton" name="G">
<property name="geometry">
<rect>
<x>390</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>G</string>
</property>
</widget>
<widget class="QPushButton" name="H">
<property name="geometry">
<rect>
<x>450</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>H</string>
</property>
</widget>
<widget class="QPushButton" name="I">
<property name="geometry">
<rect>
<x>510</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>I</string>
</property>
</widget>
<widget class="QPushButton" name="J">
<property name="geometry">
<rect>
<x>570</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>J</string>
</property>
</widget>
<widget class="QPushButton" name="K">
<property name="geometry">
<rect>
<x>630</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>K</string>
</property>
</widget>
<widget class="QPushButton" name="L">
<property name="geometry">
<rect>
<x>690</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>L</string>
</property>
</widget>
<widget class="QPushButton" name="M">
<property name="geometry">
<rect>
<x>750</x>
<y>50</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>M</string>
</property>
</widget>
<widget class="QPushButton" name="N">
<property name="geometry">
<rect>
<x>30</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>N</string>
</property>
</widget>
<widget class="QPushButton" name="O">
<property name="geometry">
<rect>
<x>90</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>O</string>
</property>
</widget>
<widget class="QPushButton" name="P">
<property name="geometry">
<rect>
<x>150</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>P</string>
</property>
</widget>
<widget class="QPushButton" name="Q">
<property name="geometry">
<rect>
<x>210</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Q</string>
</property>
</widget>
<widget class="QPushButton" name="R">
<property name="geometry">
<rect>
<x>270</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>R</string>
</property>
</widget>
<widget class="QPushButton" name="S">
<property name="geometry">
<rect>
<x>330</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>S</string>
</property>
</widget>
<widget class="QPushButton" name="T">
<property name="geometry">
<rect>
<x>390</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>T</string>
</property>
</widget>
<widget class="QPushButton" name="U">
<property name="geometry">
<rect>
<x>450</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>U</string>
</property>
</widget>
<widget class="QPushButton" name="V">
<property name="geometry">
<rect>
<x>510</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>V</string>
</property>
</widget>
<widget class="QPushButton" name="W">
<property name="geometry">
<rect>
<x>570</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>W</string>
</property>
</widget>
<widget class="QPushButton" name="X">
<property name="geometry">
<rect>
<x>630</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
<widget class="QPushButton" name="Y">
<property name="geometry">
<rect>
<x>690</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Y</string>
</property>
</widget>
<widget class="QPushButton" name="Z">
<property name="geometry">
<rect>
<x>750</x>
<y>120</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Z</string>
</property>
</widget>
</widget>
<widget class="QLabel" name="available_guess">
<property name="geometry">
<rect>
<x>120</x>
<y>160</y>
<width>141</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel{
background-color: #b3ffff;
}</string>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="newgame_button">
<property name="geometry">
<rect>
<x>310</x>
<y>550</y>
<width>251</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>START NEW GAME</string>
</property>
</widget>
<widget class="QLabel" name="error_label">
<property name="geometry">
<rect>
<x>170</x>
<y>50</y>
<width>541</width>
<height>411</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QLabel{
background-image: url(:/img/hangman.jpg); background-position: center
}</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<zorder>error_label</zorder>
<zorder>groupBox</zorder>
<zorder>word_to_guess</zorder>
<zorder>available_guess</zorder>
<zorder>newgame_button</zorder>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>936</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar">
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
</widget>
</widget>
<resources>
<include location="resource_hangman.qrc"/>
</resources>
<connections/>
</ui>
words.txt_short :
sinew sings singe sinks sinus sioux sires sired siren sisal sissy sitar sites sited sixes sixty sixth sizes sized skate skeet skein skews skids skied skier skies stoic stoke stole stoma stomp stone stony stood stool stoop stops story stork storm stoup stout stove stows strap straw stray strew stria strip strop strum strut stubs stuck studs study stuff stump stuns stung stunk stunt style suave
So far I built only the error part; meaning I press the 'start new game' button; then pressing 6 wrong letters (I mean using my 6 guesses without make the right guess, a wrong a,e,i,o,u, is minus 2 point all the rest is minus 1) of the secret word I should get the entire word and the Start the game button again.
Problem is that if I dont put either a
self.letters_guessed.clear() in line 127 of main.py or
self.letters_guessed=[] or line 128 of main.py
I am not able to show the correct secret word on screen ( 'word_to_guess' QLabel) after the 6 failed attempts, and according to my print lines on terminal after the first wrong attempt it is like the last of the wrong letters I pressed has been pressed more than once (2 in second attempt, start new game second time; 3 in third attempt, start new game third time and so on..)
As soon as I uncomment lines 127 or 128 the program behaves as expected, giving the right word after using all the guessings available.
I cant figure out why its happening, moreover the
self.letters_guessed=[] in line 65 says the same thing of line 128 and line 127 just delete the list.
Why do I need this 127 or 128 line ?
line 65 is called with start2() after pressing the start_new_game QButton (line 45)
I know I should write a minimal reproducible error (behaviour in this case)
but this is so unclear to me, that I cannot figure out any. Sorry about that
I just added
i=i.upper()
getattr(self, i).disconnect()
or
getattr(self, i).clicked.disconnect()
at the end of the
def printo(self , i):
block in main.py

PyQt5 cannot get function and classes right

Hi need help about why is not working think is conceptual but I cannot grasp it.
I have some files:
main.py :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
#author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from PyQt5.QtCore import QTimer, Qt
from inputgui import Inputgui
from checkstate import check_state
class Menu(QtWidgets.QMainWindow):
def __init__(self):
super(Menu, self).__init__()
uic.loadUi('main2.ui', self)
self.setFixedSize(544,686)
self.show()
self.ButtonC.clicked.connect(self.inputs)
def inputs(self):
self.hide()
self.inputguiwin=Inputgui()
self.inputguiwin.show()
self.validator = QtGui.QIntValidator()
self.inputguiwin.annualsalaryinput.setValidator(self.validator)
self.inputguiwin.annualsalaryinput.textChanged.connect(self.check_state)
self.inputguiwin.annualsalaryinput.textChanged.emit(self.inputguiwin.annualsalaryinput.text())
self.inputguiwin.pushButtonOK.clicked.connect(self.qpushButtonOKpressed)
self.inputguiwin.pushButtonCANCEL.clicked.connect(self.pushButtonCANCELpressed)
# def check_state(self):
# sender = self.sender()
# validator = sender.validator()
# state = validator.validate(sender.text(), 0)[0]
# if state == QtGui.QIntValidator.Acceptable:
# color = 'green'
# elif state == QtGui.QIntValidator.Intermediate:
# color = 'yellow'
# else:
# color = 'red'
# sender.setStyleSheet('QLineEdit { background-color: %s }' % color)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window=Menu()
sys.exit(app.exec_())
inputgui.py :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 14 10:40:44 2020
#author: bob
"""
import sys
from PyQt5 import QtWidgets, uic, QtCore
import resource
class Inputgui(QtWidgets.QMainWindow):
def __init__(self):
super(Inputgui, self).__init__()
uic.loadUi('inputgui2.ui', self)
self.setFixedSize(904,661)
print('inside inputgui ' *5)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
pollo=Inputgui()
sys.exit(app.exec_())
checkstate.py :
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 19 20:28:32 2020
#author: bob
"""
import sys
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from PyQt5.QtCore import QTimer, Qt
def check_state(self):
sender = self.sender()
validator = sender.validator()
state = validator.validate(sender.text(), 0)[0]
if state == QtGui.QIntValidator.Acceptable:
color = 'green'
elif state == QtGui.QIntValidator.Intermediate:
color = 'yellow'
else:
color = 'red'
sender.setStyleSheet('QLineEdit { background-color: %s }' % color)
main2.ui :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>487</width>
<height>415</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>:/main/python.png</normaloff>
<normalon>:/main/python.png</normalon>
<disabledoff>:/main/python.png</disabledoff>
<disabledon>:/main/python.png</disabledon>
<activeoff>:/main/python.png</activeoff>
<activeon>:/main/python.png</activeon>
<selectedoff>:/main/python.png</selectedoff>
<selectedon>:/main/python.png</selectedon>:/main/python.png</iconset>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="ButtonC">
<property name="geometry">
<rect>
<x>150</x>
<y>110</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>487</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
inputgui2.ui :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>276</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">QPushButton#pushButtonOK{
background-color: #9de650;
}
QPushButton:hover#pushButtonOK{
background-color: green;
}
QPushButton#pushButtonCANCEL{
background-color: orange;
}
QPushButton:hover#pushButtonCANCEL{
background-color: red;
}
</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLineEdit" name="annualsalaryinput">
<property name="geometry">
<rect>
<x>80</x>
<y>80</y>
<width>131</width>
<height>51</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string> Annual Salary</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="annualsalarylabel">
<property name="geometry">
<rect>
<x>230</x>
<y>90</y>
<width>151</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string> Annual Salary</string>
</property>
</widget>
<widget class="QLabel" name="titlelabel">
<property name="geometry">
<rect>
<x>210</x>
<y>0</y>
<width>471</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
I copied this example from the web:
open first window,
push button C,
open new window,
can only insert integer (QIntValidator),
when trying to inset input QLineEdit background change color.
Problem is I cannot get the check_state() function on an external file.
To have it work I need to have it on main.py file (add # to from checkstate import check_state
and remove #### from def check_state on main.py)
Why I cannot get the function from external file ??
On another side why QIntValidator prevents my backspace (backcancel) keyboard key to work??
You have 2 errors:
The sender() method belongs to a QObject and clearly "check_state" does not belong to any class, much less to a QObject.
"self.check_state" indicates that the class has the check_state and that is clearly not true.
So you will have to implement the logic not using sender() but passing the object through a lambda function(see this for more information):
self.inputguiwin.annualsalaryinput.textChanged.connect(lambda text, sender=self.inputguiwin.annualsalaryinput: self.check_state(sender))
def check_state(sender):
validator = sender.validator()
state = validator.validate(sender.text(), 0)[0]
# ...

How can I convert a shapely Polygon to an SVG?

I can create a Polygon by:
#!/usr/bin/env python
from shapely.geometry import Polygon
area = Polygon(((52, 13), (57, 14), (58, 12)))
with open('test.svg', 'w') as f:
f.write(area.svg())
which returns
<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 52.0,13.0 L 57.0,14.0 L 58.0,12.0 L 52.0,13.0 z" />
This is not a valid SVG file. How can I get a valid SVG?
I tried
#!/usr/bin/env python
from shapely.geometry import Polygon
area = Polygon(((52, 13), (57, 14), (58, 12)))
with open('test.svg', 'w') as f:
f.write('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">')
f.write(area.svg())
f.write('</svg>')
When I view this, the viewport is way to big for the polygon. Manually editing it with Inkscape and resizing it gives:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="test.svg"
width="7.9687681"
height="4.4396091">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1364"
id="namedview6"
showgrid="false"
inkscape:zoom="2.36"
inkscape:cx="-1.8038839"
inkscape:cy="-34.869627"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<path
d="m 0.19611614,2.3092357 4.99999996,1 1,-2 -5.99999996,1 z"
id="path4"
inkscape:connector-curvature="0"
style="opacity:0.6;fill:#66cc99;fill-rule:evenodd;stroke:#555555;stroke-width:2" />
</svg>
Is there a way to get this automatically?
try:
with open('test.svg', 'w') as f:
f.write(area._repr_svg_())
the BaseGeometry._repr_svg_ function is used for IPython/Jupyter integration, in order to render Shapely objects inline in Jupyter notebooks. Hence the "internal" naming, which is defined here:
http://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html
Effectively, it results in a valid SVG output.
You would need to specify the size and viewBox of the resulting image. For example:
#!/usr/bin/env python
from shapely.geometry import Polygon
import textwrap
area = Polygon(((52, 13), (57, 14), (58, 12)))
with open('test.svg', 'w') as f:
#specify margin in coordinate units
margin = 5
bbox = list(area.bounds)
bbox[0] -= margin
bbox[1] -= margin
bbox[2] += margin
bbox[3] += margin
width = bbox[2] - bbox[0]
height = bbox[3] - bbox[1]
#transform each coordinate unit into "scale" pixels
scale = 10
props = {
'version': '1.1',
'baseProfile': 'full',
'width': '{width:.0f}px'.format(width = width*scale),
'height': '{height:.0f}px'.format(height = height*scale),
'viewBox': '%.1f,%.1f,%.1f,%.1f' % (bbox[0], bbox[1], width, height),
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:ev': 'http://www.w3.org/2001/xml-events',
'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}
f.write(textwrap.dedent(r'''
<?xml version="1.0" encoding="utf-8" ?>
<svg {attrs:s}>
{data:s}
</svg>
''').format(
attrs = ' '.join(['{key:s}="{val:s}"'.format(key = key, val = props[key]) for key in props]),
data = area.svg()
).strip())

How can I use Glib.timeout_add() function to wait a keypress event

I am trying to create a test application. The application should list images in a directory, show the first one on screen, takes a keyboard response and show the second image, takes response, and does this for each image.
I created a glade file and I am using it to create the interface within the RavensAPM class. There is a Gtk.Window in the glade file which contains a single Gtk.Box which in turn contains a single Gtk.Image. I use run_ravens_apm() function to list images and feed images one by one to RavensAPM class. Within the RavensAPM class I update image and using show_all() present everything.
At this point I want the app to wait for a keypress event from keys [1-8] and keypad keys [1-8].
I examined the usage of GLib.timeout_add() function but I cannot be able to get the desired behavior out of it. At the moment, the for loop within the run_ravens_apm() calls RavensAPM at the same time and create as many windows as the number of images, without waiting a keyboard signal/event.
I tried to put GLib.timeout_add() within the class's __call__() method and use the instance of the class as a function, but it also did not work.
What am I doing wrong?
class RavensAPM:
def __init__(self, test_image):
self.builder = Gtk.Builder()
self.builder.add_from_file('glade/window_ravens_apm.glade')
self.window = self.builder.get_object('window_ravens_apm')
self.window.fullscreen()
self.window.connect('key-release-event', self.on_event_after)
window_height = 1080
self.pixbuf_file = \
GdkPixbuf.Pixbuf.new_from_file_at_scale(test_image,
-1,
window_height,
True)
self.image = self.builder.get_object('ravens_apm_image')
self.image.set_from_pixbuf(self.pixbuf_file)
self.window.show_all()
def on_event_after(self, widget, event):
keys = [i for i in range(49, 57)] + [i for i in range(65457, 65465)]
key_value = event.keyval
if keys in key_value:
self.window.destroy()
return False
def __call__(self):
self.on_event_after()
return True
def run_ravens_apm():
# List the contents of img/ravens_apm
# Use a loop to run RavensAPM for the length of images
interval_ms = 200
img_directory = 'img/ravens_apm'
img_files = os.listdir(img_directory)
img_files.sort()
img_files = img_files[:2]
nr_images = len(img_files)
for i in range(nr_images):
img_file = os.path.join(img_directory, img_files[i])
ravens = RavensAPM(img_file)
GLib.timeout_add(interval_ms, ravens)
print('GLib.timeout_add must wait for Gdk.EventKey event')
print(datetime.datetime.now())
Contents of the glade file is a follows.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window_ravens_apm">
<property name="can_focus">False</property>
<signal name="key-press-event" handler="on_windows_ravens_apm_key_press_event" swapped="no"/>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkImage" id="ravens_apm_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
<signal name="key-press-event" handler="on_ravens_apm_keypress" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
In case you need a longer answer I am posting my solution here. It is simple. Now I know that I should have never used Glib.timeout_add() function in the first place.
#!/usr/bin/python3
import gi
import os
import random
from gi.repository import Gtk
from gi.repository import GdkPixbuf
# from gi.repository import Gdk
# from gi.repository import GLib
gi.require_version('Gtk', '3.0')
FAKING_FIRTS = None
WINDOW_HEIGHT = 1080
class RavensAPM:
def __init__(self, img_list, window_height):
self.img_list = img_list
self.window_height = window_height
self.builder = Gtk.Builder()
self.builder.add_from_file('glade/window_ravens_apm.glade')
self.window = self.builder.get_object('window_ravens_apm')
self.window.connect('key-release-event', self.on_key_released)
self.window.fullscreen()
self.ravens_image = self.builder.get_object('ravens_apm_image')
self.pixbuf_file = \
GdkPixbuf.Pixbuf.new_from_file_at_scale(self.img_list[-1],
-1,
self.window_height,
True)
self.ravens_image.set_from_pixbuf(self.pixbuf_file)
self.window.show_all()
def on_key_released(self, widget, event):
key_value = event.keyval
keys_list = list(range(49, 57)) + list(range(65429, 65436))
if key_value in keys_list:
# TODO
# Do stg to save the keyvalue somewhere
self.img_list.pop()
self.pixbuf_file = \
GdkPixbuf.Pixbuf.new_from_file_at_scale(self.img_list[-1],
-1,
self.window_height,
True)
self.ravens_image = self.builder.get_object('ravens_apm_image')
self.ravens_image.set_from_pixbuf(self.pixbuf_file)
def run_ravens_apm():
img_directory = 'img/ravens_apm'
img_files = os.listdir(img_directory)
img_files.sort(reverse=True)
img_files = [os.path.join(img_directory, i) for i in img_files]
RavensAPM(img_files, WINDOW_HEIGHT)
Here is the Glade file I used.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window_ravens_apm">
<property name="can_focus">False</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkImage" id="ravens_apm_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
<signal name="key-press-event" handler="on_ravens_apm_keypress" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

python - writing into excel

I m new to python. actually I m able to parse an xml but don't know how to write this into excel.
sample xml:
<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
my Code:
import xml.etree.ElementTree as etree
xmld = etree.parse('simple.xml')
root = xmld.getroot()
for child in root:
for children in child:
print children.tag," : % s" %children.text
output:
name : Belgian Waffles
price : $5.95
description : Two of our famous Belgian Waffles with plenty of real maple syrup
calories : 650
name : Strawberry Belgian Waffles
price : $7.95
description : Light Belgian waffles covered with strawberries and whipped cream
calories : 900
Need to write this into excel like
'tags' into Column A and 'values' into column B
enter image description here
Tried with xlwt or openpyxl or pandas..but no luck...pls help..
From this site : http://www.python-excel.org/ , you can try :
openpyxl : https://openpyxl.readthedocs.io/en/default/
xlsxwriter : https://xlsxwriter.readthedocs.io/
xlrd : http://xlrd.readthedocs.io/en/latest/
xlwt : http://xlwt.readthedocs.io/en/latest/
xlutils : http://xlutils.readthedocs.io/en/latest/
Thanks Vlad..
i have improved my code as per below:
import xml.etree.ElementTree as etree
from openpyxl import Workbook
xmld = etree.parse('simple.xml')
root = xmld.getroot()
wb = Workbook()
ws = wb.active
for child in root:
for children in child:
#print children.tag," : % s" %children.text
for row in zip({children.tag},{children.text}):
ws.append(row)
wb.save("simple.xls")
Now i m successfully write into excel columns as expected.

Resources