def __init__(self, parent, id, title, ep_object): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__(self, parent, id, title, (550, 435), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Episode Properties') # Remember the Parent Window self.parent = parent self.obj = ep_object # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Episode ID self.id_edit = self.new_edit_box(_("Episode ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Series ID layout series_edit = self.new_edit_box(_("Series ID"), v2, self.obj.series_id) # Add the element to the sizer r2Sizer.Add(v2, 2, wx.EXPAND) series_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Dialogs.GenForm does not provide a Masked text control, so the Date # Field is handled differently than other fields. # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Date [label] date_lbl = wx.StaticText(self.panel, -1, _("Date (MM/DD/YYYY)")) v3.Add(date_lbl, 0, wx.BOTTOM, 3) # Date # Use the Masked Text Control (Requires wxPython 2.4.2.4 or later) # TODO: Make Date autoformat localizable self.dt_edit = wx.lib.masked.TextCtrl(self.panel, -1, '', autoformat='USDATEMMDDYYYY/') v3.Add(self.dt_edit, 0, wx.EXPAND) # If a Date is know, load it into the control if (self.obj.tape_date != None) and (self.obj.tape_date != '') and ( self.obj.tape_date != '01/01/0'): self.dt_edit.SetValue(self.obj.tape_date) # Add the element to the sizer r2Sizer.Add(v3, 1, wx.EXPAND) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Length self.len_edit = self.new_edit_box(_("Length"), v4, self.obj.tape_length_str()) # Add the element to the sizer r2Sizer.Add(v4, 1, wx.EXPAND) self.len_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Media Filename(s) [label] txt = wx.StaticText(self.panel, -1, _("Media Filename(s)")) mainSizer.Add(txt, 0, wx.BOTTOM, 3) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Media Filename(s) # If the media filename path is not empty, we should normalize the path specification if self.obj.media_filename == '': filePath = self.obj.media_filename else: filePath = os.path.normpath(self.obj.media_filename) # Initialize the list of media filenames with the first one. self.filenames = [filePath] # For each additional Media file ... for vid in self.obj.additional_media_files: # ... add it to the filename list self.filenames.append(vid['filename']) self.fname_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.Size(180, 60), self.filenames) # Add the element to the sizer r3Sizer.Add(self.fname_lb, 5, wx.EXPAND) self.fname_lb.SetDropTarget(ListBoxFileDropTarget(self.fname_lb)) # Add a horizontal spacer to the row sizer r3Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Add File button layout addFile = wx.Button(self.panel, wx.ID_FILE1, _("Add File"), wx.DefaultPosition) v4.Add(addFile, 0, wx.EXPAND | wx.BOTTOM, 3) wx.EVT_BUTTON(self, wx.ID_FILE1, self.OnBrowse) # Remove File button layout removeFile = wx.Button(self.panel, -1, _("Remove File"), wx.DefaultPosition) v4.Add(removeFile, 0, wx.EXPAND | wx.BOTTOM, 3) wx.EVT_BUTTON(self, removeFile.GetId(), self.OnRemoveFile) if TransanaConstants.proVersion: # SynchronizeFiles button layout synchronize = wx.Button(self.panel, -1, _("Synchronize"), wx.DefaultPosition) v4.Add(synchronize, 0, wx.EXPAND) synchronize.Bind(wx.EVT_BUTTON, self.OnSynchronize) # Add the element to the sizer r3Sizer.Add(v4, 1, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping r3Sizer.Add((2, 0)) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Comment comment_edit = self.new_edit_box(_("Comment"), v5, self.obj.comment, maxLen=255) # Add the element to the sizer r4Sizer.Add(v5, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v6.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group [list box] kw_groups_id = wx.NewId() # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, kw_groups_id, wx.DefaultPosition, wx.DefaultSize, self.kw_groups) v6.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r5Sizer.Add(v6, 1, wx.EXPAND) self.kw_list = [] wx.EVT_LISTBOX(self, kw_groups_id, self.OnGroupSelect) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v7.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, self.kw_list, style=wx.LB_EXTENDED) v7.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r5Sizer.Add(v7, 1, wx.EXPAND) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v8.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self.panel, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v8.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v8.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v8.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r5Sizer.Add(v8, 0) # Add a horizontal spacer r5Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v9 = wx.BoxSizer(wx.VERTICAL) # Episode Keywords [label] txt = wx.StaticText(self.panel, -1, _("Episode Keywords")) v9.Add(txt, 0, wx.BOTTOM, 3) # Episode Keywords [list box] # Create an empty ListBox self.ekw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, style=wx.LB_EXTENDED) v9.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r5Sizer.Add(v9, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 5, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Core Data button layout CoreData = wx.Button(self.panel, -1, _("Core Data")) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping btnSizer.Add((2, 0)) btnSizer.Add(CoreData, 0) wx.EVT_BUTTON(self, CoreData.GetId(), self.OnCoreDataClick) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(550, width), max(435, height))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(550, width), max(435, height)) # Center the form on screen self.CenterOnScreen() # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW=50, minH=20) self.kw_lb.SetSizeHints(minW=50, minH=20) self.ekw_lb.SetSizeHints(minW=50, minH=20) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) # Load the parent Series in order to determine the default Keyword Group tempSeries = Series.Series(self.obj.series_id) # Select the Series Default Keyword Group in the Keyword Group list if (tempSeries.keyword_group != '') and (self.kw_group_lb.FindString( tempSeries.keyword_group) != wx.NOT_FOUND): self.kw_group_lb.SetStringSelection(tempSeries.keyword_group) # If no Default Keyword Group is defined, select the first item in the list else: # but only if there IS a first item in the list. if len(self.kw_groups) > 0: self.kw_group_lb.SetSelection(0) if self.kw_group_lb.GetSelection() != wx.NOT_FOUND: self.kw_list = \ DBInterface.list_of_keywords_by_group(self.kw_group_lb.GetStringSelection()) else: self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) # Populate the ListBox for episodeKeyword in self.obj.keyword_list: self.ekw_lb.Append(episodeKeyword.keywordPair) self.id_edit.SetFocus()
def testLongSum(self): "Test the longSum function" self.assertEquals(Series.longSum([1,2,3,4]), 10)
def testFloatSum(self): "Test the floatSum function (to 5 decimal places)" self.assertAlmostEquals(Series.floatSum([1,2,3.14,4]), 10.14, 5)
def testShortSum(self): "Test the shortSum function" self.assertEquals(Series.shortSum([1, 2, 3, 4]), 10)
def testIntOnes(self): "Test the intOnes function" myArray = N.zeros(5,'i') Series.intOnes(myArray) N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testDoubleProd(self): "Test the doubleProd function" self.assertEquals(Series.doubleProd((1, 2.718, 3, 4)), 32.616)
def testIntMax(self): "Test the intMax function" matrix = [[6, -5, 4], [-3, 2, -1]] self.assertEquals(Series.intMax(matrix), 6)
def __init__(self, parent, id, title, note_object): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__( self, parent, id, title, size=(400, 260), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Notes' ) # 'Notes' is the Help Context for Notes. There is no entry for Note Properties at this time self.obj = note_object seriesID = '' episodeID = '' transcriptID = '' collectionID = '' clipID = '' snapshotID = '' if (self.obj.series_num != 0) and (self.obj.series_num != None): tempSeries = Series.Series(self.obj.series_num) seriesID = tempSeries.id elif (self.obj.episode_num != 0) and (self.obj.episode_num != None): tempEpisode = Episode.Episode(self.obj.episode_num) episodeID = tempEpisode.id tempSeries = Series.Series(tempEpisode.series_num) seriesID = tempSeries.id elif (self.obj.transcript_num != 0) and (self.obj.transcript_num != None): # To save time here, we can skip loading the actual transcript text, which can take time once we start dealing with images! tempTranscript = Transcript.Transcript(self.obj.transcript_num, skipText=True) transcriptID = tempTranscript.id tempEpisode = Episode.Episode(tempTranscript.episode_num) episodeID = tempEpisode.id tempSeries = Series.Series(tempEpisode.series_num) seriesID = tempSeries.id elif (self.obj.collection_num != 0) and (self.obj.collection_num != None): tempCollection = Collection.Collection(self.obj.collection_num) collectionID = tempCollection.GetNodeString() elif (self.obj.clip_num != 0) and (self.obj.clip_num != None): # We can skip loading the Clip Transcript to save load time tempClip = Clip.Clip(self.obj.clip_num, skipText=True) clipID = tempClip.id tempCollection = Collection.Collection(tempClip.collection_num) collectionID = tempCollection.GetNodeString() elif (self.obj.snapshot_num != 0) and (self.obj.snapshot_num != None): tempSnapshot = Snapshot.Snapshot(self.obj.snapshot_num) snapshotID = tempSnapshot.id tempCollection = Collection.Collection(tempSnapshot.collection_num) collectionID = tempCollection.GetNodeString() # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Note ID id_edit = self.new_edit_box(_("Note ID"), v1, self.obj.id, maxLen=100) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r2Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Series ID seriesID_edit = self.new_edit_box(_("Series ID"), v2, seriesID) # Add the element to the row sizer r2Sizer.Add(v2, 1, wx.EXPAND) seriesID_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Episode ID episodeID_edit = self.new_edit_box(_("Episode ID"), v3, episodeID) # Add the element to the row sizer r2Sizer.Add(v3, 1, wx.EXPAND) episodeID_edit.Enable(False) # Add a horizontal spacer to the row sizer r2Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Transcript ID transcriptID_edit = self.new_edit_box(_("Transcript ID"), v4, transcriptID) # Add the element to the row sizer r2Sizer.Add(v4, 1, wx.EXPAND) transcriptID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r2Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r3Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v5 = wx.BoxSizer(wx.VERTICAL) # Collection ID collectionID_edit = self.new_edit_box(_("Collection ID"), v5, collectionID) # Add the element to the row sizer r3Sizer.Add(v5, 2, wx.EXPAND) collectionID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r3Sizer, 0, wx.EXPAND) # Create a HORIZONTAL sizer for the next row r4Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v6 = wx.BoxSizer(wx.VERTICAL) # Clip ID clipID_edit = self.new_edit_box(_("Clip ID"), v6, clipID) # Add the element to the row sizer r4Sizer.Add(v6, 1, wx.EXPAND) clipID_edit.Enable(False) if TransanaConstants.proVersion: # Add a horizontal spacer to the row sizer r4Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v7 = wx.BoxSizer(wx.VERTICAL) # Snapshot ID snapshotID_edit = self.new_edit_box(_("Snapshot ID"), v7, snapshotID) # Add the element to the row sizer r4Sizer.Add(v7, 1, wx.EXPAND) snapshotID_edit.Enable(False) # Add the row sizer to the main vertical sizer mainSizer.Add(r4Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a HORIZONTAL sizer for the next row r5Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v8 = wx.BoxSizer(wx.VERTICAL) # Comment layout noteTaker_edit = self.new_edit_box(_("Note Taker"), v8, self.obj.author, maxLen=100) # Add the element to the row sizer r5Sizer.Add(v8, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r5Sizer, 0, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(400, width), height)) # Define the minimum size for this dialog as the current size, and define height as unchangeable self.SetSizeHints(max(400, width), height, -1, height) # Center the form on screen self.CenterOnScreen() # Set focus to the Note ID id_edit.SetFocus()
在数据分析中,我们更多的针对表格数据进行处理,也就是 NumPy 中的二维数组数据,尽管 NumPy 对于多维数组的支持已经足够强大,但 Pandas 处理这些二维数据时更加得心应手。Pandas 建立在 NumPy 基础之上,但增加了更加高级实用的功能,比如数据自动对齐功能,时间序列的支持,缺失数据的灵活处理等等。在接下来的实验中,我们将学习 Pandas 的基础知识,在学习的过程中一定要实践实例中的代码,只有这样才能真正掌握本节实验的内容。 在以下内容中为了演示方便,示例代码中出现的 pd, Series 和 DataFrame 已经在 IPython 终端中通过以下方式导入: In [1]: import pandas as pd In [2]: import numpy as np In [3]: from pandas import Series, DataFrame Series 和 DataFrame Series 和 DataFrame 是 Pandas 中的两种核心数据结构,大部分 Pandas 的功能都围绕着两种数据结构进行。 Series 是值的序列,可以理解为一维数组,它只有一个列和 索引。索引可以定制,当不指定时默认使用整数索引,而且索引可以被命名: In [28]: s1 = Series([1, 2, 3, 4, 5]) In [29]: s1 Out[29]: 0 1 1 2 2 3 3 4 4 5 dtype: int64 In [30]: s2 = Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e']) In [31]: s2 Out[31]: a 1
def OnDisplay(self, reportText): """ This method, required by TextReport, populates the TextReport. The reportText parameter is the wxSTC control from the TextReport object. It needs to be in the report parent because the TextReport doesn't know anything about the actual data. """ # Determine if we need to populate the Filter Lists. If it hasn't already been done, we should do it. # If it has already been done, no need to do it again. if self.filterList == []: populateFilterList = True else: populateFilterList = False # Make the control writable reportText.SetReadOnly(False) # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Set the font for the Report Title reportText.SetTxtStyle(fontFace='Courier New', fontSize=16, fontBold=True, fontUnderline=True, parAlign=wx.TEXT_ALIGNMENT_CENTER, parSpacingAfter=12) # Add the Report Title reportText.WriteText(self.title) # Turn off underlining and bold reportText.SetTxtStyle(fontBold=False, fontUnderline=False) reportText.Newline() # If we're using the Styled Text Control ... else: # Set the font for the Report Title reportText.SetFont('Courier New', 13, 0x000000, 0xFFFFFF) # Make the font Bold reportText.SetBold(True) # Get the style specified associated with this font style = reportText.GetStyleAccessor( "size:13,face:Courier New,fore:#000000,back:#ffffff,bold") # Get spaces appropriate to centering the title centerSpacer = self.report.GetCenterSpacer(style, self.title) # Insert the spaces to center the title reportText.InsertStyledText(centerSpacer) # Turn on underlining now (because we don't want the spaces to be underlined) reportText.SetUnderline(True) # Add the Report Title reportText.InsertStyledText(self.title) # Turn off underlining and bold reportText.SetUnderline(False) reportText.SetBold(False) if self.searchText != None: # ... add a subtitle if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Search Text: %s"), 'utf8') else: prompt = _("Search Text: %s") self.subtitle = prompt % self.searchText # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # ... set the font for the subtitle ... reportText.SetTxtStyle(fontSize=10) # ... and insert the spacer and the subtitle. reportText.WriteText(self.subtitle) reportText.Newline() # If we're using the Styled Text Control ... else: # ... set the font for the subtitle ... reportText.SetFont('Courier New', 10, 0x000000, 0xFFFFFF) # ... get the style specifier for that font ... style = reportText.GetStyleAccessor( "size:10,face:Courier New,fore:#000000,back:#ffffff") # ... get the spaces needed to center the subtitle ... centerSpacer = self.report.GetCenterSpacer( style, self.subtitle) # ... and insert the subtitle. reportText.InsertStyledText('\n' + centerSpacer + self.subtitle) if self.configName != '': # ... add a subtitle if 'unicode' in wx.PlatformInfo: # Encode with UTF-8 rather than TransanaGlobal.encoding because this is a prompt, not DB Data. prompt = unicode(_("Filter Configuration: %s"), 'utf8') else: prompt = _("Filter Configuration: %s") self.configLine = prompt % self.configName # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # ... set the font for the subtitle ... reportText.SetTxtStyle(fontSize=10) # ... and insert the subtitle. reportText.WriteText(self.configLine) reportText.Newline() # If we're using the Styled Text Control ... else: # ... set the font for the subtitle ... reportText.SetFont('Courier New', 10, 0x000000, 0xFFFFFF) # ... get the style specifier for that font ... style = reportText.GetStyleAccessor( "size:10,face:Courier New,fore:#000000,back:#ffffff") # ... get the spaces needed to center the subtitle ... centerSpacer = self.report.GetCenterSpacer( style, self.configLine) # ... and insert the spacer and the subtitle. reportText.InsertStyledText('\n' + centerSpacer + self.configLine) # If we're NOT using the Rich Text Control ... if not TransanaConstants.USESRTC: if (self.searchText != None) or (self.configName != ''): # Set the font for the Report Title reportText.SetFont('Courier New', 13, 0x000000, 0xFFFFFF) # Get the style specified associated with this font style = reportText.GetStyleAccessor( "size:13,face:Courier New,fore:#000000,back:#ffffff,bold") # Skip a couple of lines. reportText.InsertStyledText('\n\n') # If a Root Node flag is passed in ... if self.reportType == 'RootNode': # ... we want to group notes by category. (They will be alphabetical within each category.) majorList = DBInterface.list_of_all_notes( reportType='SeriesNode', searchText=self.searchText) majorList += DBInterface.list_of_all_notes( reportType='EpisodeNode', searchText=self.searchText) majorList += DBInterface.list_of_all_notes( reportType='TranscriptNode', searchText=self.searchText) majorList += DBInterface.list_of_all_notes( reportType='CollectionNode', searchText=self.searchText) majorList += DBInterface.list_of_all_notes( reportType='ClipNode', searchText=self.searchText) if TransanaConstants.proVersion: majorList += DBInterface.list_of_all_notes( reportType='SnapshotNode', searchText=self.searchText) # if a specific Node flag is passed in ... else: # ... and use the Clips from the Episode for the majorList. majorList = DBInterface.list_of_all_notes( reportType=self.reportType, searchText=self.searchText) # Initialize the initial data structure that will be turned into the report self.data = [] # We need a list of all checked NoteNums to apply the Filter. Initialize it here. checkedRecords = [] # Now populate it based on the Filter List. (The filterList will be empty if not populate yet, but that's OK.) # Iterate through the filter list ... for noteRecord in self.filterList: # ... pull out the filter list record elements. (noteNum, noteID, noteParent, checked) = noteRecord # If an item is checked ... if checked: # ... add it to the list of checked items! checkedRecords.append(noteNum) # Iterate through the major list for noteRecord in majorList: # If the current item from the Major List is in the list of checked records from the filter dialog # OR if we're going through the list for the first time (populateFilterList == True) .... if (noteRecord['NoteNum'] in checkedRecords) or populateFilterList: # ... load each note ... tempNote = Note.Note(noteRecord['NoteNum']) # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True, fontSize=12, parAlign=wx.TEXT_ALIGNMENT_LEFT, parLeftIndent=0, parSpacingBefore=36, parSpacingAfter=12) # Add the note ID to the report reportText.WriteText('%s' % tempNote.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText('%s\n' % tempNote.id) # Turn bold off. reportText.SetBold(False) # Initialize all temporary objects to None so we can detect their presence or absence tempSeries = None tempEpisode = None tempTranscript = None tempCollection = None tempClip = None tempSnapshot = None # If we have a Series Note ... if tempNote.series_num > 0: # ... load the Series data tempSeries = Series.Series(tempNote.series_num) noteParent = unicode(_('Series'), 'utf8') + ' ' + tempSeries.id # If we have an Episode Note ... elif tempNote.episode_num > 0: # ... load the Episode and Series data tempEpisode = Episode.Episode(tempNote.episode_num) tempSeries = Series.Series(tempEpisode.series_num) noteParent = unicode( _('Episode'), 'utf8') + ' ' + tempSeries.id + ' > ' + tempEpisode.id # If we have a Transcript Note ... elif tempNote.transcript_num > 0: # ... load the Transcript, Episode, and Series data # To save time here, we can skip loading the actual transcript text, which can take time once we start dealing with images! tempTranscript = Transcript.Transcript( tempNote.transcript_num, skipText=True) tempEpisode = Episode.Episode(tempTranscript.episode_num) tempSeries = Series.Series(tempEpisode.series_num) noteParent = unicode( _('Transcript'), 'utf8' ) + ' ' + tempSeries.id + ' > ' + tempEpisode.id + ' > ' + tempTranscript.id # If we have a Collection Note ... elif tempNote.collection_num > 0: # ... load the Collection data tempCollection = Collection.Collection( tempNote.collection_num) noteParent = unicode( _('Collection'), 'utf8') + ' ' + tempCollection.GetNodeString() # If we have a Clip Note ... elif tempNote.clip_num > 0: # ... load the Clip and Collection data. We can skip loading the Clip Transcript to save load time tempClip = Clip.Clip(tempNote.clip_num, skipText=True) tempCollection = Collection.Collection( tempClip.collection_num) noteParent = unicode( _('Clip'), 'utf8') + ' ' + tempCollection.GetNodeString( ) + ' > ' + tempClip.id # If we have a Snapshot Note ... elif tempNote.snapshot_num > 0: # ... load the Snapshot and Collection data. tempSnapshot = Snapshot.Snapshot(tempNote.snapshot_num) tempCollection = Collection.Collection( tempSnapshot.collection_num) noteParent = unicode( _('Snapshot'), 'utf8') + ' ' + tempCollection.GetNodeString( ) + ' > ' + tempSnapshot.id # If we have Series data ... if tempSeries != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontSize=10, fontBold=True, parLeftIndent=63, parSpacingBefore=0, parSpacingAfter=0) # Add the note ID to the report reportText.WriteText(_('Series: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Series ID reportText.WriteText('%s' % tempSeries.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Series: ')) # Turn bold off. reportText.SetBold(False) # Add the Series ID reportText.InsertStyledText('%s\n' % tempSeries.id) # If we have Episode data ... if tempEpisode != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Episode: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Episode ID reportText.WriteText('%s' % tempEpisode.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Episode: ')) # Turn bold off. reportText.SetBold(False) # Add the Episode ID reportText.InsertStyledText('%s\n' % tempEpisode.id) # If we have Transcript data ... if tempTranscript != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Transcript: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Transcript ID reportText.WriteText('%s' % tempTranscript.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Transcript: ')) # Turn bold off. reportText.SetBold(False) # Add the Transcript ID reportText.InsertStyledText('%s\n' % tempTranscript.id) # If we have Collection data ... if tempCollection != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontSize=10, fontBold=True, parLeftIndent=63, parSpacingBefore=0, parSpacingAfter=0) # Add the note ID to the report reportText.WriteText(_('Collection: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Collection ID reportText.WriteText('%s' % tempCollection.GetNodeString()) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Collection: ')) # Turn bold off. reportText.SetBold(False) # Add the Collection Node String reportText.InsertStyledText( '%s\n' % tempCollection.GetNodeString()) # If we have Clip data ... if tempClip != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Clip: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Clip ID reportText.WriteText('%s' % tempClip.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Clip: ')) # Turn bold off. reportText.SetBold(False) # Add the Clip ID reportText.InsertStyledText('%s\n' % tempClip.id) # If we have Snapshot data ... if tempSnapshot != None: # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Snapshot: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Snapshot ID reportText.WriteText('%s' % tempSnapshot.id) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Snapshot: ')) # Turn bold off. reportText.SetBold(False) # Add the Snapshot ID reportText.InsertStyledText('%s\n' % tempSnapshot.id) # If we're going through the list for the first time and need to populate the filter list ... if populateFilterList: # ... add the note number, note ID, note parent info, and checked=True to the filter list. self.filterList.append( (tempNote.number, tempNote.id, noteParent, True)) # If we're using the Rich Text Control ... if TransanaConstants.USESRTC: # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Note Taker: ')) # Turn bold off. reportText.SetTxtStyle(fontBold=False) # Add the Note's author reportText.WriteText('%s' % tempNote.author) reportText.Newline() # Turn bold on. reportText.SetTxtStyle(fontBold=True) # Add the note ID to the report reportText.WriteText(_('Note Text:')) reportText.Newline() # Turn bold off. reportText.SetTxtStyle(fontBold=False, parLeftIndent=127) # Add the note text to the report (rstrip() prevents formatting problems when notes end with blank lines) reportText.WriteText('%s' % tempNote.text.rstrip()) reportText.Newline() # If we're using the Styled Text Control ... else: # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Note Taker: ')) # Turn bold off. reportText.SetBold(False) # Add the Note's author reportText.InsertStyledText('%s\n' % tempNote.author) # Turn bold on. reportText.SetBold(True) # Add the note ID to the report reportText.InsertStyledText(_('Note Text:\n')) # Turn bold off. reportText.SetBold(False) # Add the note text to the report reportText.InsertStyledText('%s\n' % tempNote.text.rstrip()) # Add a blank line after each group reportText.InsertStyledText('\n') # Make the control read only, now that it's done reportText.SetReadOnly(True)
def main(): Series.Series( "http://www.cricbuzz.com/cricket-series/2538/the-ashes-2017-18/matches" )
def __init__(self, dbTree, searchCount, kwg=None, kw=None, searchName=None, searchTerms=None): """ Initialize the ProcessSearch class. The dbTree parameter accepts a wxTreeCtrl as the Database Tree where Search Results should be displayed. The searchCount parameter accepts the number that should be included in the Default Search Title. Optional kwg (Keyword Group) and kw (Keyword) parameters implement Quick Search for the keyword specified. """ # Note the Database Tree that accepts Search Results self.dbTree = dbTree self.collectionList = [] # If kwg and kw are None, we are doing a regular (full) search. if ((kwg == None) or (kw == None)) and (searchTerms == None): # Create the Search Dialog Box dlg = SearchDialog.SearchDialog(_("Search") + " %s" % searchCount) # Display the Search Dialog Box and record the Result result = dlg.ShowModal() # If the user selects OK ... if result == wx.ID_OK: # ... get the search name from the dialog searchName = dlg.searchName.GetValue().strip() # Search Name is required. If it was eliminated, put it back! if searchName == '': searchName = _("Search") + " %s" % searchCount # Get the Collections Tree from the Search Form collTree = dlg.ctcCollections # Get the Collections Tree's Root Node collNode = collTree.GetRootItem() # Get a list of all the Checked Collections in the Collections Tree self.collectionList = dlg.GetCollectionList( collTree, collNode, True) # ... and get the search terms from the dialog searchTerms = dlg.searchQuery.GetValue().split('\n') # Get the includeEpisodes info includeEpisodes = dlg.includeEpisodes.IsChecked() # Get the includeClips info includeClips = dlg.includeClips.IsChecked() # Get the includeSnapshots info includeSnapshots = dlg.includeSnapshots.IsChecked() # Destroy the Search Dialog Box dlg.Destroy() elif (searchTerms != None): # There's no dialog. Just say the user said OK. result = wx.ID_OK # Include Episodes, Clips, and Snapshots includeEpisodes = True includeClips = True if TransanaConstants.proVersion: includeSnapshots = True else: includeSnapshots = False # if kwg and kw are passed in, we're doing a Quick Search else: # There's no dialog. Just say the user said OK. result = wx.ID_OK # The Search Name is built from the kwg : kw combination searchName = "%s : %s" % (kwg, kw) # The Search Terms are just the keyword group and keyword passed in searchTerms = ["%s:%s" % (kwg, kw)] # Include Episodes, Clips and Snapshots includeEpisodes = True includeClips = True if TransanaConstants.proVersion: includeSnapshots = True else: includeSnapshots = False # If OK is pressed (or Quick Search), process the requested Search if result == wx.ID_OK: # Increment the Search Counter self.searchCount = searchCount + 1 # The "Search" node itself is always item 0 in the node list searchNode = self.dbTree.select_Node((_("Search"), ), 'SearchRootNode') # We need to collect a list of the named searches already done. namedSearches = [] # Get the first child node from the Search root node (childNode, cookieVal) = self.dbTree.GetFirstChild(searchNode) # As long as there are child nodes ... while childNode.IsOk(): # Add the node name to the named searches list ... namedSearches.append(self.dbTree.GetItemText(childNode)) # ... and get the next child node (childNode, cookieVal) = self.dbTree.GetNextChild(childNode, cookieVal) # We need to give each search result a unique name. So note the search count number nameIncrementValue = searchCount # As long as there's already a named search with the name we want to use ... while (searchName in namedSearches): # ... if this is our FIRST attempt ... if nameIncrementValue == searchCount: # ... append the appropriate number on the end of the search name searchName += unicode(_(' - Search %d'), 'utf8') % nameIncrementValue # ... if this is NOT our first attempt ... else: # ... remove the previous number and add the appropriate next number to try searchName = searchName[:searchName.rfind( ' ')] + ' %d' % nameIncrementValue # Increment our counter by one. We'll keep trying new numbers until we find one that works. nameIncrementValue += 1 # As long as there's a search name (and there's no longer a way to eliminate it! if searchName != '': # Add a Search Results Node to the Database Tree nodeListBase = [_("Search"), searchName] self.dbTree.add_Node('SearchResultsNode', nodeListBase, 0, 0, expandNode=True) # Build the appropriate Queries based on the Search Query specified in the Search Dialog. # (This method parses the Natural Language Search Terms into queries for Episode Search # Terms, for Clip Search Terms, and for Snapshot Search Terms, and includes the appropriate # Parameters to be used with the queries. Parameters are not integrated into the queries # in order to allow for automatic processing of apostrophes and other text that could # otherwise interfere with the SQL execution.) (episodeQuery, clipQuery, wholeSnapshotQuery, snapshotCodingQuery, params) = self.BuildQueries(searchTerms) # Get a Database Cursor dbCursor = DBInterface.get_db().cursor() if includeEpisodes: # Adjust query for sqlite, if needed episodeQuery = DBInterface.FixQuery(episodeQuery) # Execute the Series/Episode query dbCursor.execute(episodeQuery, tuple(params)) # Process the results of the Series/Episode query for line in DBInterface.fetchall_named(dbCursor): # Add the new Transcript(s) to the Database Tree Tab. # To add a Transcript, we need to build the node list for the tree's add_Node method to climb. # We need to add the Series, Episode, and Transcripts to our Node List, so we'll start by loading # the current Series and Episode tempSeries = Series.Series(line['SeriesNum']) tempEpisode = Episode.Episode(line['EpisodeNum']) # Add the Search Root Node, the Search Name, and the current Series and Episode Names. nodeList = (_('Search'), searchName, tempSeries.id, tempEpisode.id) # Find out what Transcripts exist for each Episode transcriptList = DBInterface.list_transcripts( tempSeries.id, tempEpisode.id) # If the Episode HAS defined transcripts ... if len(transcriptList) > 0: # Add each Transcript to the Database Tree for (transcriptNum, transcriptID, episodeNum) in transcriptList: # Add the Transcript Node to the Tree. self.dbTree.add_Node( 'SearchTranscriptNode', nodeList + (transcriptID, ), transcriptNum, episodeNum) # If the Episode has no transcripts, it still has the keywords and SHOULD be displayed! else: # Add the Transcript-less Episode Node to the Tree. self.dbTree.add_Node('SearchEpisodeNode', nodeList, tempEpisode.number, tempSeries.number) if includeClips: # Adjust query for sqlite, if needed clipQuery = DBInterface.FixQuery(clipQuery) # Execute the Collection/Clip query dbCursor.execute(clipQuery, params) # Process all results of the Collection/Clip query for line in DBInterface.fetchall_named(dbCursor): # Add the new Clip to the Database Tree Tab. # To add a Clip, we need to build the node list for the tree's add_Node method to climb. # We need to add all of the Collection Parents to our Node List, so we'll start by loading # the current Collection tempCollection = Collection.Collection( line['CollectNum']) # Add the current Collection Name, and work backwards from here. nodeList = (tempCollection.id, ) # Repeat this process as long as the Collection we're looking at has a defined Parent... while tempCollection.parent > 0: # Load the Parent Collection tempCollection = Collection.Collection( tempCollection.parent) # Add this Collection's name to the FRONT of the Node List nodeList = (tempCollection.id, ) + nodeList # Get the DB Values tempID = line['ClipID'] # If we're in Unicode mode, format the strings appropriately if 'unicode' in wx.PlatformInfo: tempID = DBInterface.ProcessDBDataForUTF8Encoding( tempID) # Now add the Search Root Node and the Search Name to the front of the Node List and the # Clip Name to the back of the Node List nodeList = (_('Search'), searchName) + nodeList + (tempID, ) # Add the Node to the Tree self.dbTree.add_Node('SearchClipNode', nodeList, line['ClipNum'], line['CollectNum'], sortOrder=line['SortOrder']) if includeSnapshots: # Adjust query for sqlite, if needed wholeSnapshotQuery = DBInterface.FixQuery( wholeSnapshotQuery) # Execute the Whole Snapshot query dbCursor.execute(wholeSnapshotQuery, params) # Since we have two sources of Snapshots that get included, we need to track what we've already # added so we don't add the same Snapshot twice addedSnapshots = [] # Process all results of the Whole Snapshot query for line in DBInterface.fetchall_named(dbCursor): # Add the new Snapshot to the Database Tree Tab. # To add a Snapshot, we need to build the node list for the tree's add_Node method to climb. # We need to add all of the Collection Parents to our Node List, so we'll start by loading # the current Collection tempCollection = Collection.Collection( line['CollectNum']) # Add the current Collection Name, and work backwards from here. nodeList = (tempCollection.id, ) # Repeat this process as long as the Collection we're looking at has a defined Parent... while tempCollection.parent > 0: # Load the Parent Collection tempCollection = Collection.Collection( tempCollection.parent) # Add this Collection's name to the FRONT of the Node List nodeList = (tempCollection.id, ) + nodeList # Get the DB Values tempID = line['SnapshotID'] # If we're in Unicode mode, format the strings appropriately if 'unicode' in wx.PlatformInfo: tempID = DBInterface.ProcessDBDataForUTF8Encoding( tempID) # Now add the Search Root Node and the Search Name to the front of the Node List and the # Clip Name to the back of the Node List nodeList = (_('Search'), searchName) + nodeList + (tempID, ) # Add the Node to the Tree self.dbTree.add_Node('SearchSnapshotNode', nodeList, line['SnapshotNum'], line['CollectNum'], sortOrder=line['SortOrder']) # Add the Snapshot to the list of Snapshots added to the Search Result addedSnapshots.append(line['SnapshotNum']) tmpNode = self.dbTree.select_Node( nodeList[:-1], 'SearchCollectionNode', ensureVisible=False) self.dbTree.SortChildren(tmpNode) # Adjust query for sqlite if needed snapshotCodingQuery = DBInterface.FixQuery( snapshotCodingQuery) # Execute the Snapshot Coding query dbCursor.execute(snapshotCodingQuery, params) # Process all results of the Snapshot Coding query for line in DBInterface.fetchall_named(dbCursor): # If the Snapshot is NOT already in the Search Results ... if not (line['SnapshotNum'] in addedSnapshots): # Add the new Snapshot to the Database Tree Tab. # To add a Snapshot, we need to build the node list for the tree's add_Node method to climb. # We need to add all of the Collection Parents to our Node List, so we'll start by loading # the current Collection tempCollection = Collection.Collection( line['CollectNum']) # Add the current Collection Name, and work backwards from here. nodeList = (tempCollection.id, ) # Repeat this process as long as the Collection we're looking at has a defined Parent... while tempCollection.parent > 0: # Load the Parent Collection tempCollection = Collection.Collection( tempCollection.parent) # Add this Collection's name to the FRONT of the Node List nodeList = (tempCollection.id, ) + nodeList # Get the DB Values tempID = line['SnapshotID'] # If we're in Unicode mode, format the strings appropriately if 'unicode' in wx.PlatformInfo: tempID = DBInterface.ProcessDBDataForUTF8Encoding( tempID) # Now add the Search Root Node and the Search Name to the front of the Node List and the # Clip Name to the back of the Node List nodeList = (_('Search'), searchName) + nodeList + (tempID, ) # Add the Node to the Tree self.dbTree.add_Node('SearchSnapshotNode', nodeList, line['SnapshotNum'], line['CollectNum'], sortOrder=line['SortOrder']) # Add the Snapshot to the list of Snapshots added to the Search Result addedSnapshots.append(line['SnapshotNum']) tmpNode = self.dbTree.select_Node( nodeList[:-1], 'SearchCollectionNode', ensureVisible=False) self.dbTree.SortChildren(tmpNode) else: self.searchCount = searchCount # If the Search Dialog is cancelled, do NOT increment the Search Number else: self.searchCount = searchCount
def activeEvnt(self, obj, evnt): if self.check.active: if not Series.Series().get(self.serie.id): Series.Series().add(self.serie) else: Series.Series().rm(self.serie.id)
def build(self): series = Series.Series() # series.searchInComicVine('Green Arrow') # self.listaComics = series.listaComicVineSearch carousel = KivyAllSeriesGui([]) return carousel
import Series from pandas print(Series([1, 2, 3]))
def __init__(self, parent, id): obj = Series() obj.owner = DBInterface.get_username() SeriesPropertiesForm.__init__(self, parent, id, _("Add Series"), obj)
def __init__(self, parent, id, title, obj, keywords): # Make the Keyword Edit List resizable by passing wx.RESIZE_BORDER style Dialogs.GenForm.__init__( self, parent, id, title, size=TransanaGlobal.configData.keywordListEditSize, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, useSizers=True, HelpContext='Edit Keywords') # Remember the parent Window self.parent = parent self.obj = obj # if Keywords that server as Keyword Examples are removed, we will need to remember them. # Then, when OK is pressed, the Keyword Example references in the Database Tree can be removed. # We can't remove them immediately in case the whole Clip Properties Edit process is cancelled. self.keywordExamplesToDelete = [] # COPY the keyword list, rather than just pointing to it, so that the list on this form will # be independent of the original list. That way, pressing CANCEL does not cause the list to # be changed anyway, though it means that if OK is pressed, you must copy the list to update # it in the calling routine. self.keywords = [] for kws in keywords: self.keywords.append(kws) # Create the form's main VERTICAL sizer mainSizer = wx.BoxSizer(wx.VERTICAL) # Create a HORIZONTAL sizer for the first row r1Sizer = wx.BoxSizer(wx.HORIZONTAL) # Create a VERTICAL sizer for the next element v1 = wx.BoxSizer(wx.VERTICAL) # Keyword Group [label] txt = wx.StaticText(self.panel, -1, _("Keyword Group")) v1.Add(txt, 0, wx.BOTTOM, 3) # Keyword Group layout [list box] # Create an empty Keyword Group List for now. We'll populate it later (for layout reasons) self.kw_groups = [] self.kw_group_lb = wx.ListBox(self.panel, 101, wx.DefaultPosition, wx.DefaultSize, self.kw_groups) v1.Add(self.kw_group_lb, 1, wx.EXPAND) # Add the element to the sizer r1Sizer.Add(v1, 1, wx.EXPAND) self.kw_list = [] wx.EVT_LISTBOX(self, 101, self.OnGroupSelect) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v2 = wx.BoxSizer(wx.VERTICAL) # Keyword [label] txt = wx.StaticText(self.panel, -1, _("Keyword")) v2.Add(txt, 0, wx.BOTTOM, 3) # Keyword [list box] self.kw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, self.kw_list, style=wx.LB_EXTENDED) v2.Add(self.kw_lb, 1, wx.EXPAND) wx.EVT_LISTBOX_DCLICK(self, self.kw_lb.GetId(), self.OnAddKW) # Add the element to the sizer r1Sizer.Add(v2, 1, wx.EXPAND) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v3 = wx.BoxSizer(wx.VERTICAL) # Keyword transfer buttons add_kw = wx.Button(self.panel, wx.ID_FILE2, ">>", wx.DefaultPosition) v3.Add(add_kw, 0, wx.EXPAND | wx.TOP, 20) wx.EVT_BUTTON(self, wx.ID_FILE2, self.OnAddKW) rm_kw = wx.Button(self.panel, wx.ID_FILE3, "<<", wx.DefaultPosition) v3.Add(rm_kw, 0, wx.EXPAND | wx.TOP, 10) wx.EVT_BUTTON(self, wx.ID_FILE3, self.OnRemoveKW) kwm = wx.BitmapButton(self.panel, wx.ID_FILE4, TransanaImages.KWManage.GetBitmap()) v3.Add(kwm, 0, wx.EXPAND | wx.TOP, 10) # Add a spacer to increase the height of the Keywords section v3.Add((0, 60)) kwm.SetToolTipString(_("Keyword Management")) wx.EVT_BUTTON(self, wx.ID_FILE4, self.OnKWManage) # Add the element to the sizer r1Sizer.Add(v3, 0) # Add a horizontal spacer r1Sizer.Add((10, 0)) # Create a VERTICAL sizer for the next element v4 = wx.BoxSizer(wx.VERTICAL) # Keywords [label] txt = wx.StaticText(self.panel, -1, _("Keywords")) v4.Add(txt, 0, wx.BOTTOM, 3) # Keywords [list box] # Create an empty ListBox self.ekw_lb = wx.ListBox(self.panel, -1, wx.DefaultPosition, wx.DefaultSize, style=wx.LB_EXTENDED) v4.Add(self.ekw_lb, 1, wx.EXPAND) self.ekw_lb.Bind(wx.EVT_KEY_DOWN, self.OnKeywordKeyDown) # Add the element to the sizer r1Sizer.Add(v4, 2, wx.EXPAND) # Add the row sizer to the main vertical sizer mainSizer.Add(r1Sizer, 1, wx.EXPAND) # Add a vertical spacer to the main sizer mainSizer.Add((0, 10)) # Create a sizer for the buttons btnSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the buttons self.create_buttons(sizer=btnSizer) # Add the button sizer to the main sizer mainSizer.Add(btnSizer, 0, wx.EXPAND) # If Mac ... if 'wxMac' in wx.PlatformInfo: # ... add a spacer to avoid control clipping mainSizer.Add((0, 2)) # Set the PANEL's main sizer self.panel.SetSizer(mainSizer) # Tell the PANEL to auto-layout self.panel.SetAutoLayout(True) # Lay out the Panel self.panel.Layout() # Lay out the panel on the form self.Layout() # Resize the form to fit the contents self.Fit() # Get the new size of the form (width, height) = self.GetSizeTuple() # Reset the form's size to be at least the specified minimum width self.SetSize(wx.Size(max(600, width), max(385, height))) # Define the minimum size for this dialog as the current size self.SetSizeHints(max(600, width), max(385, height)) # Center the form on screen self.CenterOnScreen() # We need to set some minimum sizes so the sizers will work right self.kw_group_lb.SetSizeHints(minW=50, minH=20) self.kw_lb.SetSizeHints(minW=50, minH=20) self.ekw_lb.SetSizeHints(minW=50, minH=20) # We need to capture the OK and Cancel button clicks locally. We'll use FindWindowByID to locate the correct widgets. self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(wx.ID_OK)) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.FindWindowById(wx.ID_CANCEL)) # We populate the Keyword Groups, Keywords, and Clip Keywords lists AFTER we determine the Form Size. # Long Keywords in the list were making the form too big! # Obtain the list of Keyword Groups self.kw_groups = DBInterface.list_of_keyword_groups() for keywordGroup in self.kw_groups: self.kw_group_lb.Append(keywordGroup) if self.kw_group_lb.GetCount() > 0: self.kw_group_lb.EnsureVisible(0) # Get the Parent Object, so we can know the Default Keyword Group if isinstance(self.obj, Episode.Episode): objParent = Series.Series(self.obj.series_num) elif isinstance(self.obj, Clip.Clip) or isinstance( self.obj, Snapshot.Snapshot): objParent = Collection.Collection(self.obj.collection_num) if len(self.kw_groups) > 0: # Set the Keyword Group to the Default keyword Group if self.kw_group_lb.FindString( objParent.keyword_group) != wx.NOT_FOUND: self.kw_group_lb.SetStringSelection(objParent.keyword_group) else: self.kw_group_lb.SetSelection(0) # Obtain the list of Keywords for the intial Keyword Group self.kw_list = DBInterface.list_of_keywords_by_group( self.kw_group_lb.GetStringSelection()) else: self.kw_list = [] for keyword in self.kw_list: self.kw_lb.Append(keyword) if self.kw_lb.GetCount() > 0: self.kw_lb.EnsureVisible(0) # Populate the ListBox for clipKeyword in self.keywords: self.ekw_lb.Append(clipKeyword.keywordPair) if self.ekw_lb.GetCount() > 0: self.ekw_lb.EnsureVisible(0) self.kw_group_lb.SetFocus()
def testDoubleSum(self): "Test the doubleSum function" self.assertEquals(Series.doubleSum([1,2,3.14,4]), 10.14)
def testDoubleOnes(self): "Test the doubleOnes function" myArray = N.zeros(5, 'd') Series.doubleOnes(myArray) N.testing.assert_array_equal(myArray, N.array([1., 1., 1., 1., 1.]))
def testDoubleProd(self): "Test the doubleProd function" self.assertEquals(Series.doubleProd((1,2.718,3,4)), 32.616)
def testDoubleMax(self): "Test the doubleMax function" matrix = [[-6, 5, -4], [3.14, -2.718, 1]] self.assertEquals(Series.doubleMax(matrix), 5.0)
def testDoubleZeros(self): "Test the doubleZeros function" myArray = N.ones(5,'d') Series.doubleZeros(myArray) N.testing.assert_array_equal(myArray, N.array([0.,0.,0.,0.,0.]))
Pandas 绘图 matplotlib 绘制图像已经够方便,但是更多的时候我们使用 Pandas 分析数据,并把数据保存在 DataFrame 数据对象中。幸运的是,Pandas 已经高度整合了 matplotlib, 可以直接直接调用DataFrame 对象的某些方法进行绘图,更加方便的时候 DataFrame 的标签信息(列名称)会自动绘制到图形上。 以下示例代码中的 Series, Dataframe, np, plt, pd 已经通过以下代码导入: In [82]: import matplotlib.pyplot as plt In [83]: import numpy as np In [84]: import pandas as pd In [85]: from pandas import Series, DataFrame 可以直接在 Series 对象上绘制线形图,如下代码: In [79]: s = Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10)) In [80]: s.plot() Out[80]: <matplotlib.axes._subplots.AxesSubplot at 0x117e3e588> In [81]: plt.show() 或者在 DataFrame 对象上绘制箱线图: In [86]: df = pd.DataFrame(np.random.rand(5,4), columns=['A', 'B', 'C', 'D']) In [87]: df.boxplot() Out[87]: <matplotlib.axes._subplots.AxesSubplot at 0x115c2f5f8> In [88]: plt.show() 可以看到非常方便,在前文中展示的各种常用图形,Pandas 都可以直接进行绘制,并自动添加标签等信息。
def testDoubleOnes(self): "Test the doubleOnes function" myArray = N.zeros(5,'d') Series.doubleOnes(myArray) N.testing.assert_array_equal(myArray, N.array([1.,1.,1.,1.,1.]))
def testIntNegate(self): "Test the intNegate function" myArray = N.arange(5,dtype='i') Series.intNegate(myArray) N.testing.assert_array_equal(myArray, N.array([0,-1,-2,-3,-4]))
def testDoubleNegate(self): "Test the doubleNegate function" myArray = N.arange(5) * 1.0 Series.doubleNegate(myArray) N.testing.assert_array_equal(myArray, N.array([0.,-1.,-2.,-3.,-4.]))
def testLongProd(self): "Test the longProd function" self.assertEquals(Series.longProd([1,2,3,4]), 24)
def testIntMax(self): "Test the intMax function" matrix = [[6,-5,4],[-3,2,-1]] self.assertEquals(Series.intMax(matrix), 6)
def testFloatProd(self): "Test the floatProd function (to 5 decimal places)" self.assertAlmostEquals(Series.floatProd((1,2.718,3,4)), 32.616, 5)
def testIntFloor(self): "Test the intFloor function" matrix = N.array([[10,-2],[-6,7]]) Series.intFloor(matrix,0) N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
import Series as s import SVGHelperFunctions xdat = [50, 100] ydat = [50, 100] series = s.Series(xdat, ydat, "test") series.svg.save()
def testDoubleMax(self): "Test the doubleMax function" matrix = [[-6,5,-4],[3.14,-2.718,1]] self.assertEquals(Series.doubleMax(matrix), 5.0)
def test4(): obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4]) print(obj3) obj4 = obj3.reset_index(drop=True) print(obj4) print( type(obj4))
def testDoubleFloor(self): "Test the doubleFloor function" matrix = N.array([[10,-2.718],[-6,3.14]]) Series.doubleFloor(matrix,5.0) N.testing.assert_array_equal(matrix, N.array([[10.0,0],[0,0]]))
def testDoubleSum(self): "Test the doubleSum function" self.assertEquals(Series.doubleSum([1, 2, 3.14, 4]), 10.14)
def testShortSum(self): "Test the shortSum function" self.assertEquals(Series.shortSum([1,2,3,4]), 10)
def testDoubleZeros(self): "Test the doubleZeros function" myArray = N.ones(5, 'd') Series.doubleZeros(myArray) N.testing.assert_array_equal(myArray, N.array([0., 0., 0., 0., 0.]))
def testShortProd(self): "Test the shortProd function" self.assertEquals(Series.shortProd([1,2,3,4]), 24)
def testDoubleNegate(self): "Test the doubleNegate function" myArray = N.arange(5) * 1.0 Series.doubleNegate(myArray) N.testing.assert_array_equal(myArray, N.array([0., -1., -2., -3., -4.]))
def testIntSum(self): "Test the intSum function" self.assertEquals(Series.intSum([1,2,3,4]), 10)
def testIntFloor(self): "Test the intFloor function" matrix = N.array([[10, -2], [-6, 7]]) Series.intFloor(matrix, 0) N.testing.assert_array_equal(matrix, N.array([[10, 0], [0, 7]]))
def testIntProd(self): "Test the intProd function" self.assertEquals(Series.intProd([1,2,3,4]), 24)
def testDoubleFloor(self): "Test the doubleFloor function" matrix = N.array([[10, -2.718], [-6, 3.14]]) Series.doubleFloor(matrix, 5.0) N.testing.assert_array_equal(matrix, N.array([[10.0, 0], [0, 0]]))
def testIntZeros(self): "Test the intZeros function" myArray = N.ones(5,'i') Series.intZeros(myArray) N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
def testShortProd(self): "Test the shortProd function" self.assertEquals(Series.shortProd([1, 2, 3, 4]), 24)