<commit_before># -*- coding: utf-8 -*-
""" controller actions for E15Contest and E15Nominee

    :copyright: Copyright (c) 2015 Bivio Software, Inc.  All Rights Reserved.
    :license: Apache, see LICENSE for more details.
"""

import datetime
import flask
import json
import pytz
import random
import werkzeug.exceptions

from . import form as pef
from . import model as pem
from .. import biv
from .. import common
from .. import controller as ppc
from ..auth import model as pam
from ..general import oauth
from ..contest import model as pcm

_template = common.Template('evc2015')

class E15Contest(ppc.Task):
    """Contest actions"""

    @common.decorator_login_required
    @common.decorator_user_is_admin
    def action_admin_review_nominees(biv_obj):
        nominees = pem.E15Nominee.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == biv_obj.biv_id,
            pam.BivAccess.target_biv_id == pem.E15Nominee.biv_id
        ).all()
        nominees = sorted(nominees, key=lambda nominee: nominee.display_name)
        res = []
        for nominee in nominees:
            submitter = E15Contest._nominee_submitter(nominee)
            res.append({
                'biv_id': nominee.biv_id,
                'display_name': nominee.display_name,
                'url': nominee.url,
                'youtube_code': nominee.youtube_code,
                'nominee_desc': nominee.nominee_desc,
                'is_public': nominee.is_public,
                'founders': E15Contest._founder_info_for_nominee(nominee),
                'submitter_display_name': submitter.display_name,
                'submitter_email': submitter.user_email,
            })
        return flask.jsonify({
            'nominees': res,
        })

    @common.decorator_login_required
    @common.decorator_user_is_admin
    def action_admin_set_nominee_visibility(biv_obj):
        data = flask.request.get_json()
        nominee_biv_id = data['biv_id']
        is_public = data['is_public']
        nominee = pem.E15Nominee.query.filter_by(
            biv_id=nominee_biv_id,
        ).first_or_404()
        nominee.is_public = is_public
        ppc.db.session.add(nominee)
        return '{}'

    def action_contest_info(biv_obj):
        tz = pytz.timezone('US/Mountain')
        end_of_day = tz.localize(
            datetime.datetime(
                2015, 10, 14,
                23, 59, 59))
        seconds_remaining = (end_of_day - datetime.datetime.now(tz)).total_seconds()
        return flask.jsonify({
            'allowNominations': seconds_remaining > 0,
            'contestantCount': len(E15Contest._public_nominees(biv_obj)),
        })

    def action_index(biv_obj):
        """Returns angular app home"""
        return _template.render_template(
            biv_obj,
            'index',
            version='20151020',
        )

    @common.decorator_login_required
    @common.decorator_user_is_judge
    def action_judge_ranking(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominees = E15Contest._public_nominees(biv_obj)
        ranks, comments = E15Contest._judge_ranks_and_comments_for_nominees(flask.session.get('user.biv_id'), nominees)

        for biv_id in ranks:
            ppc.db.session.delete(ranks[biv_id])

        for biv_id in comments:
            ppc.db.session.delete(comments[biv_id])

        for nominee in data['nominees']:
            if 'rank' in nominee and nominee['rank']:
                ppc.db.session.add(
                    pcm.JudgeRank(
                        judge_biv_id=flask.session['user.biv_id'],
                        nominee_biv_id=biv.URI(nominee['biv_id']).biv_id,
                        judge_rank=nominee['rank'])
                )
            if 'comment' in nominee and nominee['comment']:
                ppc.db.session.add(
                    pcm.JudgeComment(
                        judge_biv_id=flask.session['user.biv_id'],
                        nominee_biv_id=biv.URI(nominee['biv_id']).biv_id,
                        judge_comment=nominee['comment'])
                )
        return ''

    @common.decorator_login_required
    @common.decorator_user_is_judge
    def action_judging(biv_obj):
        nominees = E15Contest._public_nominees(biv_obj)
        random.Random(flask.session.get('user.display_name')).shuffle(nominees)
        ranks, comments = E15Contest._judge_ranks_and_comments_for_nominees(flask.session.get('user.biv_id'), nominees)

        res = []
        for nominee in nominees:
            biv_id = str(nominee.biv_id)
            res.append({
                'biv_id': biv.Id(nominee.biv_id).to_biv_uri(),
                'display_name': nominee.display_name,
                'rank': ranks[biv_id].judge_rank if biv_id in ranks else None,
                'comment': comments[biv_id].judge_comment if biv_id in comments else None,
            })
        return flask.jsonify({
            'judging': res,
        })

    def action_logout(biv_obj):
        oauth.logout()
        return E15Contest.action_user_state(biv_obj)

    def action_new_test_judge(biv_obj):
        """Creates a new test user and judge models and log in."""
        return pcm.Judge.new_test_judge(biv_obj)

    def action_nominee_form_metadata(biv_obj):
        form = pef.Nominate()
        res = []
        for field in form:
            res.append({
                'name': field.name,
                'type': field.type,
                'label': field.label.text,
                'helpText': form.help_text(field.name),
            })
        return flask.jsonify(form_metadata=res)

    def action_nominee_form_submit(biv_obj):
        #TODO(pjm): need decorator for this
        if not flask.session.get('user.is_logged_in'):
            werkzeug.exceptions.abort(403)
        return flask.jsonify(pef.Nominate().execute(biv_obj))

    def action_nominee_info(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominee_biv_id = biv.URI(data['nominee_biv_id']).biv_id
        # ensure the Nominee is related to this contest
        pam.BivAccess.query.filter_by(
            source_biv_id=biv_obj.biv_id,
            target_biv_id=nominee_biv_id,
        ).first_or_404()
        nominee = pem.E15Nominee.query.filter_by(
            biv_id=nominee_biv_id,
        ).first_or_404()
        return flask.jsonify(nominee={
            'biv_id': nominee.biv_id,
            'display_name': nominee.display_name,
            'url': nominee.url,
            'youtube_code': nominee.youtube_code,
            'nominee_desc': nominee.nominee_desc,
            'founders': E15Contest._founder_info_for_nominee(nominee),
        })

    def action_public_nominee_list(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominees = E15Contest._public_nominees(biv_obj)
        random.Random(data['random_value']).shuffle(nominees)
        res = []
        for nominee in nominees:
            res.append({
                'biv_id': biv.Id(nominee.biv_id).to_biv_uri(),
                'display_name': nominee.display_name,
                'youtube_code': nominee.youtube_code,
                'nominee_summary': common.summary_text(nominee.nominee_desc),
            })
        return flask.jsonify({
            'nominees': res,
        })

    def action_rules(biv_obj):
        return flask.redirect('/static/pdf/20150914-evc-rules.pdf')

    def action_sponsors(biv_obj):
        return flask.jsonify(sponsors=biv_obj.get_sponsors())

    def action_user_state(biv_obj):
        logged_in = True if flask.session.get('user.is_logged_in') else False
        return flask.jsonify(user_state={
            'is_logged_in': logged_in,
            'is_admin': pam.Admin.is_admin(),
            'is_judge': biv_obj.is_judge(),
            'display_name': flask.session.get('user.display_name') if logged_in else '',
        })

    def get_template():
        return _template

    def _founder_info_for_nominee(nominee):
        founders = pcm.Founder.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == nominee.biv_id,
            pam.BivAccess.target_biv_id == pcm.Founder.biv_id
        ).all()
        res = []
        for founder in founders:
            res.append({
                'biv_id': founder.biv_id,
                'display_name': founder.display_name,
                'founder_desc': founder.founder_desc,
            })
        return res

    def _nominee_submitter(nominee):
        return  pam.User.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == pam.User.biv_id,
            pam.BivAccess.target_biv_id == nominee.biv_id,
        ).first_or_404()

    def _judge_ranks_and_comments_for_nominees(user_id, nominees):
        nominee_ids = []
        for nominee in nominees:
            nominee_ids.append(nominee.biv_id)

        ranks = {}
        for rank in (pcm.JudgeRank.query.filter(
                pcm.JudgeRank.nominee_biv_id.in_(nominee_ids)
        ).filter_by(
                judge_biv_id=user_id,
        ).all()):
            ranks[str(rank.nominee_biv_id)] = rank

        comments = {}
        for comment in (pcm.JudgeComment.query.filter(
                pcm.JudgeComment.nominee_biv_id.in_(nominee_ids)
        ).filter_by(
                judge_biv_id=user_id,
        ).all()):
            comments[str(comment.nominee_biv_id)] = comment
        return (ranks, comments)

    def _public_nominees(contest):
        return pem.E15Nominee.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == contest.biv_id,
            pam.BivAccess.target_biv_id == pem.E15Nominee.biv_id,
            pem.E15Nominee.is_public == True,
        ).all()
<commit_msg>incremented version<commit_after># -*- coding: utf-8 -*-
""" controller actions for E15Contest and E15Nominee

    :copyright: Copyright (c) 2015 Bivio Software, Inc.  All Rights Reserved.
    :license: Apache, see LICENSE for more details.
"""

import datetime
import flask
import json
import pytz
import random
import werkzeug.exceptions

from . import form as pef
from . import model as pem
from .. import biv
from .. import common
from .. import controller as ppc
from ..auth import model as pam
from ..general import oauth
from ..contest import model as pcm

_template = common.Template('evc2015')

class E15Contest(ppc.Task):
    """Contest actions"""

    @common.decorator_login_required
    @common.decorator_user_is_admin
    def action_admin_review_nominees(biv_obj):
        nominees = pem.E15Nominee.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == biv_obj.biv_id,
            pam.BivAccess.target_biv_id == pem.E15Nominee.biv_id
        ).all()
        nominees = sorted(nominees, key=lambda nominee: nominee.display_name)
        res = []
        for nominee in nominees:
            submitter = E15Contest._nominee_submitter(nominee)
            res.append({
                'biv_id': nominee.biv_id,
                'display_name': nominee.display_name,
                'url': nominee.url,
                'youtube_code': nominee.youtube_code,
                'nominee_desc': nominee.nominee_desc,
                'is_public': nominee.is_public,
                'founders': E15Contest._founder_info_for_nominee(nominee),
                'submitter_display_name': submitter.display_name,
                'submitter_email': submitter.user_email,
            })
        return flask.jsonify({
            'nominees': res,
        })

    @common.decorator_login_required
    @common.decorator_user_is_admin
    def action_admin_set_nominee_visibility(biv_obj):
        data = flask.request.get_json()
        nominee_biv_id = data['biv_id']
        is_public = data['is_public']
        nominee = pem.E15Nominee.query.filter_by(
            biv_id=nominee_biv_id,
        ).first_or_404()
        nominee.is_public = is_public
        ppc.db.session.add(nominee)
        return '{}'

    def action_contest_info(biv_obj):
        tz = pytz.timezone('US/Mountain')
        end_of_day = tz.localize(
            datetime.datetime(
                2015, 10, 14,
                23, 59, 59))
        seconds_remaining = (end_of_day - datetime.datetime.now(tz)).total_seconds()
        return flask.jsonify({
            'allowNominations': seconds_remaining > 0,
            'contestantCount': len(E15Contest._public_nominees(biv_obj)),
        })

    def action_index(biv_obj):
        """Returns angular app home"""
        return _template.render_template(
            biv_obj,
            'index',
            version='20151021',
        )

    @common.decorator_login_required
    @common.decorator_user_is_judge
    def action_judge_ranking(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominees = E15Contest._public_nominees(biv_obj)
        ranks, comments = E15Contest._judge_ranks_and_comments_for_nominees(flask.session.get('user.biv_id'), nominees)

        for biv_id in ranks:
            ppc.db.session.delete(ranks[biv_id])

        for biv_id in comments:
            ppc.db.session.delete(comments[biv_id])

        for nominee in data['nominees']:
            if 'rank' in nominee and nominee['rank']:
                ppc.db.session.add(
                    pcm.JudgeRank(
                        judge_biv_id=flask.session['user.biv_id'],
                        nominee_biv_id=biv.URI(nominee['biv_id']).biv_id,
                        judge_rank=nominee['rank'])
                )
            if 'comment' in nominee and nominee['comment']:
                ppc.db.session.add(
                    pcm.JudgeComment(
                        judge_biv_id=flask.session['user.biv_id'],
                        nominee_biv_id=biv.URI(nominee['biv_id']).biv_id,
                        judge_comment=nominee['comment'])
                )
        return ''

    @common.decorator_login_required
    @common.decorator_user_is_judge
    def action_judging(biv_obj):
        nominees = E15Contest._public_nominees(biv_obj)
        random.Random(flask.session.get('user.display_name')).shuffle(nominees)
        ranks, comments = E15Contest._judge_ranks_and_comments_for_nominees(flask.session.get('user.biv_id'), nominees)

        res = []
        for nominee in nominees:
            biv_id = str(nominee.biv_id)
            res.append({
                'biv_id': biv.Id(nominee.biv_id).to_biv_uri(),
                'display_name': nominee.display_name,
                'rank': ranks[biv_id].judge_rank if biv_id in ranks else None,
                'comment': comments[biv_id].judge_comment if biv_id in comments else None,
            })
        return flask.jsonify({
            'judging': res,
        })

    def action_logout(biv_obj):
        oauth.logout()
        return E15Contest.action_user_state(biv_obj)

    def action_new_test_judge(biv_obj):
        """Creates a new test user and judge models and log in."""
        return pcm.Judge.new_test_judge(biv_obj)

    def action_nominee_form_metadata(biv_obj):
        form = pef.Nominate()
        res = []
        for field in form:
            res.append({
                'name': field.name,
                'type': field.type,
                'label': field.label.text,
                'helpText': form.help_text(field.name),
            })
        return flask.jsonify(form_metadata=res)

    def action_nominee_form_submit(biv_obj):
        #TODO(pjm): need decorator for this
        if not flask.session.get('user.is_logged_in'):
            werkzeug.exceptions.abort(403)
        return flask.jsonify(pef.Nominate().execute(biv_obj))

    def action_nominee_info(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominee_biv_id = biv.URI(data['nominee_biv_id']).biv_id
        # ensure the Nominee is related to this contest
        pam.BivAccess.query.filter_by(
            source_biv_id=biv_obj.biv_id,
            target_biv_id=nominee_biv_id,
        ).first_or_404()
        nominee = pem.E15Nominee.query.filter_by(
            biv_id=nominee_biv_id,
        ).first_or_404()
        return flask.jsonify(nominee={
            'biv_id': nominee.biv_id,
            'display_name': nominee.display_name,
            'url': nominee.url,
            'youtube_code': nominee.youtube_code,
            'nominee_desc': nominee.nominee_desc,
            'founders': E15Contest._founder_info_for_nominee(nominee),
        })

    def action_public_nominee_list(biv_obj):
        data = json.loads(flask.request.data.decode('unicode-escape'))
        nominees = E15Contest._public_nominees(biv_obj)
        random.Random(data['random_value']).shuffle(nominees)
        res = []
        for nominee in nominees:
            res.append({
                'biv_id': biv.Id(nominee.biv_id).to_biv_uri(),
                'display_name': nominee.display_name,
                'youtube_code': nominee.youtube_code,
                'nominee_summary': common.summary_text(nominee.nominee_desc),
            })
        return flask.jsonify({
            'nominees': res,
        })

    def action_rules(biv_obj):
        return flask.redirect('/static/pdf/20150914-evc-rules.pdf')

    def action_sponsors(biv_obj):
        return flask.jsonify(sponsors=biv_obj.get_sponsors())

    def action_user_state(biv_obj):
        logged_in = True if flask.session.get('user.is_logged_in') else False
        return flask.jsonify(user_state={
            'is_logged_in': logged_in,
            'is_admin': pam.Admin.is_admin(),
            'is_judge': biv_obj.is_judge(),
            'display_name': flask.session.get('user.display_name') if logged_in else '',
        })

    def get_template():
        return _template

    def _founder_info_for_nominee(nominee):
        founders = pcm.Founder.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == nominee.biv_id,
            pam.BivAccess.target_biv_id == pcm.Founder.biv_id
        ).all()
        res = []
        for founder in founders:
            res.append({
                'biv_id': founder.biv_id,
                'display_name': founder.display_name,
                'founder_desc': founder.founder_desc,
            })
        return res

    def _nominee_submitter(nominee):
        return  pam.User.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == pam.User.biv_id,
            pam.BivAccess.target_biv_id == nominee.biv_id,
        ).first_or_404()

    def _judge_ranks_and_comments_for_nominees(user_id, nominees):
        nominee_ids = []
        for nominee in nominees:
            nominee_ids.append(nominee.biv_id)

        ranks = {}
        for rank in (pcm.JudgeRank.query.filter(
                pcm.JudgeRank.nominee_biv_id.in_(nominee_ids)
        ).filter_by(
                judge_biv_id=user_id,
        ).all()):
            ranks[str(rank.nominee_biv_id)] = rank

        comments = {}
        for comment in (pcm.JudgeComment.query.filter(
                pcm.JudgeComment.nominee_biv_id.in_(nominee_ids)
        ).filter_by(
                judge_biv_id=user_id,
        ).all()):
            comments[str(comment.nominee_biv_id)] = comment
        return (ranks, comments)

    def _public_nominees(contest):
        return pem.E15Nominee.query.select_from(pam.BivAccess).filter(
            pam.BivAccess.source_biv_id == contest.biv_id,
            pam.BivAccess.target_biv_id == pem.E15Nominee.biv_id,
            pem.E15Nominee.is_public == True,
        ).all()
<|endoftext|>


<commit_before>"""
  @file   ItemMenu.py
  @author Brian Kim
  @brief  defines the command-line interface for the item menu
"""

from inv.model.Permissions import Permissions
from inv.model.Item import Item
from common import *

class ItemMenu():
  class Delegate():
    """
    a set of methods that should be defined by the using
    class in order to respond to interface events
    """
    def itemMenuCheckUserPermission( self, action ):
      """
      determine whether a user has permission
      to perform a certain action
      """
      return True

    #
    # view methods
    #
    def itemMenuListAll( self):
      """
      return: all items in the db
      """
      return []

    #
    # edit methods
    #
    def itemMenuWantsEdit( self, item ):
      """
      receives the item that has been modified
      return: 0 for success, negative num for error
      """
      return -1

    #
    # add/remove methods
    #
    def itemMenuWantsAdd( self, item ):
      """
      receives the item that wants to be created (no id)
      """
      return -1

    def itemMenuWantsDelete( self, item ):
      """
      receives the item that has wants to be deleted
      return: 0 for success, negative num for error
      """
      return -1

    #
    # view methods
    #
    def itemMenuLookupByManufacturer( self, manufacturer ):
      """
      looking up items by manufacturer
      return: a list of matching items
      """
      return []

    def itemMenuLookupByCategory( self, category ):
      """
      looking up items by manufacturer
      return: a list of matching items
      """
      return []

  """
  Menu class definition
  """
  def __init__( self, delegate=Delegate() ):
    """
    just looking to set the delegate
    """
    self.delegate=delegate

  def main( self ):
    """
    prints out the item main menu
    """
    # set default option
    opt = 0
    # display the menu repeatedly until back is selected
    while opt != 5:
      print ""
      print "============"
      print "Item Menu"
      print "============"
      print "1. View"
      print "2. Edit"
      print "3. Add"
      print "4. Remove"
      print "5. Back"
      print ""
      opt = read_int('Select an option: ')

      # go through all the option values and check permissions
      if opt == 1 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemRead):
        self.viewMenu()
      elif opt == 2 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemUpdate):
        self.editMenu()
      elif opt == 3 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemCreate):
        self.addMenu()
      elif opt == 4 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemDelete):
        self.removeMenu()
      elif opt != 5:
        print "Invalid option (maybe insufficient permissions?), try again..."

  def listItemMenu( self ):
    """
    displays a menu of possible ways to search through items
    and then returns a list of those items
    """
    print ""
    print "============"
    print "List Items "
    print "============"
    print "1. Lookup by Category"
    print "2. Lookup by Manufacturer"
    print "3. List all"
    print ""
    opt = read_int('Select an option: ')

    # go through the options...
    if opt == 1: # lookup by category
      print ""
      x = read_str("Category: ")
      y = self.delegate.itemMenuLookupByCategory(x)
    elif opt == 2: # lookup by manufacturer
      print ""
      x = read_str("Manufacturer: ")
      y = self.delegate.itemMenuLookupByManufacturer(x)
    elif opt == 3: # list all items
      y = self.delegate.itemMenuListAll()
    else: # any other option will repeat this menu
      y = self.listItemMenu()
    return y

  def selectItemMenu( self, x=[] ):
    """
    displays a list of items 'x' and then asks the user to select
    an item, returning that item
    """
    # check list length
    n = len(x)
    # check for empty list
    if n == 0:
      print ""
      print "No Results Found..."
      return None
    # print out the list
    print ""
    print str(x) + "Results:"
    for i in len(x):
      item = x[i]
      print str(i+1)+". "+str(item)
    # get index
    opt = -1                 # to make sure we get a valid index...
    while opt != -1:         # until opt is NOT equal to -1
      print ""
      opt = read_int("Select an item: ")
      if opt < 1 or opt > n: # if opt falls outside the proper range,
        opt = -1             # set it back to -1

    # get that item
    y = x[opt-1]
    return y

  def displayItemInfo( self, x=None ):
    """
    displays the contents of an item
    """
    # check for null obj
    if x == None:
      return

    # repeatedly display the item info until back
      print ""
      print "==================="
      print "Item Information"
      print "==================="
      print "Category: " + x.category
      print "Manufacturer: " + x.manufacturer
      print "Model: " + x.model
      print ""

  def getItem( self ):
    """
    convenience method to retrieve an item from a list search
    """
    itemlist = self.listItemMenu()
    item = self.selectItemMenu(itemlist)
    return item

  def itemViewMenu( self, x ):
    """
    method to display a menu after viewing an item
    """
    opt = 0
    while opt != 3:
      print ""
      print "What would you like to do?"
      print "1. edit"
      print "2. remove"
      print "3. back"
      print ""
      opt = read_int('Select an option: ')

      if opt == 1: # edit
        self.editItem(x)
      elif opt == 2: # remove
        if self.removeItem(x):
          return
      elif opt != 3: # other (not back)
        print ""
        print "invalid option, try again..."
        self.itemViewMenu(x) # try again

  def editItemMenu( self, x ):
    """
    method to prompt the editing of the item fields
    """
    if x == None:
      return None

    print ""
    # read category
    category = read_str( 'Category: ' )
    x.category = category if category != '' else x.category # check empty input
    # read category
    manufacturer = read_str( 'Manufacturer: ' )
    x.manufacturer = manufacturer if manufacturer != '' else x.manufacturer # check empty input
    # read category
    model = read_str( 'Model: ' )
    x.model = model if model != '' else x.model # check empty input
    # set the fields
    return x

  def editItem( self, x ):
    """
    method to edit the item and then save the changes
    also checks for successful save and displays the proper error msg
    """
    # edit the item
    print ""
    print "============"
    print "Item Edit"
    print "============"
    item = self.editItemMenu(x)
    # request the delegate to save the edit
    if self.delegate.itemMenuWantsEdit(item) == 0:
      print "Successfully saved!"
    else:
      print "Failed to save, try again later..."

  def confirmDelete():
    """
    prompts a confirm delete message
    """
    print ""
    return read_bool('Are you sure you want to delete this item (y/n)? ')

  def removeItem( self, x ):
    """
    method to edit the item and then save the changes
    also checks for successful save and displays the proper error msg
    """
    # confirm the delete
    if self.confirmDelete() == False:
      return

    # request the delegate to delete the item
    if self.delegate.itemMenuWantsDelete(item) == 0:
      print "Successfully removed!"
    else:
      print "Failed to remove, try again later..."

  def viewMenu( self ):
    """
    gets an item
    displays that item's information
    asks if the user wants to do anything more
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.itemViewMenu(item)

  def editMenu( self ):
    """
    gets an item
    displays that item's information
    prompts the edits that are to be made
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.editItem(item)

  def addMenu( self ):
    """
    creates an empty item
    edits that item
    tries to save that item
    """
    item = Item()
    print ""
    print "============"
    print "Add Item"
    print "============"
    item = self.editItemMenu(item)
    if self.delegate.itemMenuWantsAdd(item) == 0:
      print "Successfully saved!"
    else:
      print "Failed to add, try again later..."

  def removeMenu( self ):
    """
    gets an item
    displays that item's information
    removes that item
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.removeItem(item)
<commit_msg>bug fixes<commit_after>"""
  @file   ItemMenu.py
  @author Brian Kim
  @brief  defines the command-line interface for the item menu
"""

from inv.model.Permissions import Permissions
from inv.model.Item import Item
from common import *

class ItemMenu():
  class Delegate():
    """
    a set of methods that should be defined by the using
    class in order to respond to interface events
    """
    def itemMenuCheckUserPermission( self, action ):
      """
      determine whether a user has permission
      to perform a certain action
      """
      return True

    #
    # view methods
    #
    def itemMenuListAll( self):
      """
      return: all items in the db
      """
      return []

    #
    # edit methods
    #
    def itemMenuWantsEdit( self, item ):
      """
      receives the item that has been modified
      return: 0 for success, negative num for error
      """
      return -1

    #
    # add/remove methods
    #
    def itemMenuWantsAdd( self, item ):
      """
      receives the item that wants to be created (no id)
      """
      return -1

    def itemMenuWantsDelete( self, item ):
      """
      receives the item that has wants to be deleted
      return: 0 for success, negative num for error
      """
      return -1

    #
    # view methods
    #
    def itemMenuLookupByManufacturer( self, manufacturer ):
      """
      looking up items by manufacturer
      return: a list of matching items
      """
      return []

    def itemMenuLookupByCategory( self, category ):
      """
      looking up items by manufacturer
      return: a list of matching items
      """
      return []

  """
  Menu class definition
  """
  def __init__( self, delegate=Delegate() ):
    """
    just looking to set the delegate
    """
    self.delegate=delegate

  def main( self ):
    """
    prints out the item main menu
    """
    # set default option
    opt = 0
    # display the menu repeatedly until back is selected
    while opt != 5:
      print ""
      print "============"
      print "Item Menu"
      print "============"
      print "1. View"
      print "2. Edit"
      print "3. Add"
      print "4. Remove"
      print "5. Back"
      print ""
      opt = read_int('Select an option: ')

      # go through all the option values and check permissions
      if opt == 1 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemRead):
        self.viewMenu()
      elif opt == 2 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemUpdate):
        self.editMenu()
      elif opt == 3 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemCreate):
        self.addMenu()
      elif opt == 4 and self.delegate.itemMenuCheckUserPermission(Permissions.ItemDelete):
        self.removeMenu()
      elif opt != 5:
        print "Invalid option (maybe insufficient permissions?), try again..."

  def listItemMenu( self ):
    """
    displays a menu of possible ways to search through items
    and then returns a list of those items
    """
    print ""
    print "============"
    print "List Items "
    print "============"
    print "1. Lookup by Category"
    print "2. Lookup by Manufacturer"
    print "3. List all"
    print ""
    opt = read_int('Select an option: ')

    # go through the options...
    if opt == 1: # lookup by category
      print ""
      x = read_str("Category: ")
      y = self.delegate.itemMenuLookupByCategory(x)
    elif opt == 2: # lookup by manufacturer
      print ""
      x = read_str("Manufacturer: ")
      y = self.delegate.itemMenuLookupByManufacturer(x)
    elif opt == 3: # list all items
      y = self.delegate.itemMenuListAll()
    else: # any other option will repeat this menu
      y = self.listItemMenu()
    return y

  def selectItemMenu( self, x=[] ):
    """
    displays a list of items 'x' and then asks the user to select
    an item, returning that item
    """
    # check list length
    n = len(x)
    # check for empty list
    if n == 0:
      print ""
      print "No Results Found..."
      return None
    # print out the list
    print ""
    print str(n) + " Results:"
    for i in range(n):
      item = x[i]
      print str(i+1)+". "+str(item)

    # get index
    opt = -1                 # to make sure we get a valid index...
    while opt == -1:         # until opt is NOT equal to -1
      print ""
      opt = read_int("Select an item: ")
      if opt < 1 or opt > n: # if opt falls outside the proper range,
        opt = -1             # set it back to -1

    # get that item
    y = x[opt-1]
    return y

  def displayItemInfo( self, x=None ):
    """
    displays the contents of an item
    """
    # check for null obj
    if x == None:
      return

    # display the item info until back
    print ""
    print "==================="
    print "Item Information"
    print "==================="
    print "Category: " + x.category
    print "Manufacturer: " + x.manufacturer
    print "Model: " + x.model
    print ""

  def getItem( self ):
    """
    convenience method to retrieve an item from a list search
    """
    itemlist = self.listItemMenu()
    if itemlist == None:
      return None
    item = self.selectItemMenu(itemlist)
    return item

  def itemViewMenu( self, x ):
    """
    method to display a menu after viewing an item
    """
    # display the information
    self.displayItemInfo(x)

    # request action
    opt = 0
    while opt != 3:
      print ""
      print "What would you like to do?"
      print "1. edit"
      print "2. remove"
      print "3. back"
      print ""
      opt = read_int('Select an option: ')

      if opt == 1: # edit
        self.displayItemInfo(x)
        self.editItem(x)
      elif opt == 2: # remove
        if self.removeItem(x):
          return
      elif opt != 3: # other (not back)
        print ""
        print "invalid option, try again..."
        self.itemViewMenu(x) # try again

  def editItemMenu( self, x ):
    """
    method to prompt the editing of the item fields
    """
    if x == None:
      return None

    print ""
    # read category
    category = read_str( 'Category: ' )
    x.category = category if category != '' else x.category # check empty input
    # read category
    manufacturer = read_str( 'Manufacturer: ' )
    x.manufacturer = manufacturer if manufacturer != '' else x.manufacturer # check empty input
    # read category
    model = read_str( 'Model: ' )
    x.model = model if model != '' else x.model # check empty input
    # set the fields
    return x

  def editItem( self, x ):
    """
    method to edit the item and then save the changes
    also checks for successful save and displays the proper error msg
    """
    # edit the item
    print ""
    print "============"
    print "Item Edit"
    print "============"
    item = self.editItemMenu(x)
    # request the delegate to save the edit
    if self.delegate.itemMenuWantsEdit(item) == 0:
      print "Successfully saved!"
    else:
      print "Failed to save, try again later..."

  def confirmDelete():
    """
    prompts a confirm delete message
    """
    print ""
    return read_bool('Are you sure you want to delete this item (y/n)? ')

  def removeItem( self, x ):
    """
    method to edit the item and then save the changes
    also checks for successful save and displays the proper error msg
    """
    # confirm the delete
    if self.confirmDelete() == False:
      return

    # request the delegate to delete the item
    if self.delegate.itemMenuWantsDelete(item) == 0:
      print "Successfully removed!"
    else:
      print "Failed to remove, try again later..."

  def viewMenu( self ):
    """
    gets an item
    displays that item's information
    asks if the user wants to do anything more
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.itemViewMenu(item)

  def editMenu( self ):
    """
    gets an item
    displays that item's information
    prompts the edits that are to be made
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.editItem(item)

  def addMenu( self ):
    """
    creates an empty item
    edits that item
    tries to save that item
    """
    item = Item()
    print ""
    print "============"
    print "Add Item"
    print "============"
    item = self.editItemMenu(item)
    if self.delegate.itemMenuWantsAdd(item) == 0:
      print "Successfully saved!"
    else:
      print "Failed to add, try again later..."

  def removeMenu( self ):
    """
    gets an item
    displays that item's information
    removes that item
    """
    item = self.getItem()
    if item == None:
      return
    self.displayItemInfo(item)
    self.removeItem(item)
<|endoftext|>


<commit_before>
""" Classes for representing outcomes on master and slavenode sides
"""

# WARNING! is_critical is debugging flag which means something
#          wrong went on a different level. Usually that means
#          internal bug.

import sys
import py

class Outcome(object):
    def __init__(self, setupfailure=False, excinfo=None, skipped=None,
            is_critical=False):
        self.passed = not excinfo and not skipped
        self.skipped = skipped
        self.setupfailure = setupfailure
        self.excinfo = excinfo
        self.is_critical = is_critical
        self.signal = 0
        self.stdout = "" # XXX temporary
        self.stderr = ""
        assert bool(self.passed) + bool(excinfo) + bool(skipped) == 1

    def make_excinfo_repr(self, tbstyle):
        if self.excinfo is None:
            return None
        excinfo = self.excinfo
        tb_info = [self.traceback_entry_repr(x, tbstyle)
                   for x in excinfo.traceback]
        rec_index = excinfo.traceback.recursionindex()
        if hasattr(excinfo, 'type'):
            etype = excinfo.type
            if hasattr(etype, '__name__'):
                etype = etype.__name__
        else:
            etype = excinfo.typename
        val = getattr(excinfo, 'value', None)
        if not val:
            val = exinfo.exconly()
        val = str(val)
        return (etype, val, (tb_info, rec_index))

    def traceback_entry_repr(self, tb_entry, tb_style):
        lineno = tb_entry.lineno
        relline = lineno - tb_entry.frame.code.firstlineno
        path = str(tb_entry.path)
        #try:
        try:
            if tb_style == 'long':
                source = str(tb_entry.getsource())
            else:
                source = str(tb_entry.getsource()).split("\n")[relline]
        except py.error.ENOENT:
            source = "[cannot get source]"
        name = str(tb_entry.frame.code.name)
        # XXX: Bare except. What can getsource() raise anyway?
        # SyntaxError, AttributeError, IndentationError for sure, check it
        #except:
        #    source = "<could not get source>"
        return (relline, lineno, source, path, name)

    def make_repr(self, tbstyle="long"):
        return (self.passed, self.setupfailure,
                self.make_excinfo_repr(tbstyle),
                self.skipped, self.is_critical, 0, self.stdout, self.stderr)

class TracebackEntryRepr(object):
    def __init__(self, tbentry):
        relline, lineno, self.source, self.path, self.name = tbentry
        self.relline = int(relline)
        self.path = py.path.local(self.path)
        self.lineno = int(lineno)
        self.locals = {}

    def __repr__(self):
        return "line %s in %s\n  %s" %(self.lineno, self.path, self.source[100:])

    def getsource(self):
        return py.code.Source(self.source).strip()

    def getfirstlinesource(self):
        return self.lineno - self.relline

class TracebackRepr(list):
    def recursionindex(self):
        return self.recursion_index

class ExcInfoRepr(object):
    def __init__(self, excinfo):
        self.typename, self.value, tb_i = excinfo
        tb, rec_index = tb_i
        self.traceback = TracebackRepr([TracebackEntryRepr(x) for x in tb])
        self.traceback.recursion_index = rec_index

    def __repr__(self):
        l = ["%s=%s" %(x, getattr(self, x))
                for x in "typename value traceback".split()]
        return "<ExcInfoRepr %s>" %(" ".join(l),)

    def exconly(self, tryshort=False):
        """ Somehow crippled version of original one
        """
        return "%s: %s" % (self.typename, self.value)

    def errisinstance(self, exc_t):
        if not isinstance(exc_t, tuple):
            exc_t = (exc_t,)
        for exc in exc_t:
            if self.typename == str(exc).split('.')[-1]:
                return True
        return False

class ReprOutcome(object):
    def __init__(self, repr_tuple):
        (self.passed, self.setupfailure, excinfo, self.skipped,
         self.is_critical, self.signal, self.stdout, self.stderr) = repr_tuple
        if excinfo is None:
            self.excinfo = None
        else:
            self.excinfo = ExcInfoRepr(excinfo)

    def __repr__(self):
        l = ["%s=%s" %(x, getattr(self, x))
                for x in "signal passed skipped setupfailure excinfo stdout stderr".split()]
        return "<ReprOutcome %s>" %(" ".join(l),)
<commit_msg>[svn r38576] typo!<commit_after>
""" Classes for representing outcomes on master and slavenode sides
"""

# WARNING! is_critical is debugging flag which means something
#          wrong went on a different level. Usually that means
#          internal bug.

import sys
import py

class Outcome(object):
    def __init__(self, setupfailure=False, excinfo=None, skipped=None,
            is_critical=False):
        self.passed = not excinfo and not skipped
        self.skipped = skipped
        self.setupfailure = setupfailure
        self.excinfo = excinfo
        self.is_critical = is_critical
        self.signal = 0
        self.stdout = "" # XXX temporary
        self.stderr = ""
        assert bool(self.passed) + bool(excinfo) + bool(skipped) == 1

    def make_excinfo_repr(self, tbstyle):
        if self.excinfo is None:
            return None
        excinfo = self.excinfo
        tb_info = [self.traceback_entry_repr(x, tbstyle)
                   for x in excinfo.traceback]
        rec_index = excinfo.traceback.recursionindex()
        if hasattr(excinfo, 'type'):
            etype = excinfo.type
            if hasattr(etype, '__name__'):
                etype = etype.__name__
        else:
            etype = excinfo.typename
        val = getattr(excinfo, 'value', None)
        if not val:
            val = excinfo.exconly()
        val = str(val)
        return (etype, val, (tb_info, rec_index))

    def traceback_entry_repr(self, tb_entry, tb_style):
        lineno = tb_entry.lineno
        relline = lineno - tb_entry.frame.code.firstlineno
        path = str(tb_entry.path)
        #try:
        try:
            if tb_style == 'long':
                source = str(tb_entry.getsource())
            else:
                source = str(tb_entry.getsource()).split("\n")[relline]
        except py.error.ENOENT:
            source = "[cannot get source]"
        name = str(tb_entry.frame.code.name)
        # XXX: Bare except. What can getsource() raise anyway?
        # SyntaxError, AttributeError, IndentationError for sure, check it
        #except:
        #    source = "<could not get source>"
        return (relline, lineno, source, path, name)

    def make_repr(self, tbstyle="long"):
        return (self.passed, self.setupfailure,
                self.make_excinfo_repr(tbstyle),
                self.skipped, self.is_critical, 0, self.stdout, self.stderr)

class TracebackEntryRepr(object):
    def __init__(self, tbentry):
        relline, lineno, self.source, self.path, self.name = tbentry
        self.relline = int(relline)
        self.path = py.path.local(self.path)
        self.lineno = int(lineno)
        self.locals = {}

    def __repr__(self):
        return "line %s in %s\n  %s" %(self.lineno, self.path, self.source[100:])

    def getsource(self):
        return py.code.Source(self.source).strip()

    def getfirstlinesource(self):
        return self.lineno - self.relline

class TracebackRepr(list):
    def recursionindex(self):
        return self.recursion_index

class ExcInfoRepr(object):
    def __init__(self, excinfo):
        self.typename, self.value, tb_i = excinfo
        tb, rec_index = tb_i
        self.traceback = TracebackRepr([TracebackEntryRepr(x) for x in tb])
        self.traceback.recursion_index = rec_index

    def __repr__(self):
        l = ["%s=%s" %(x, getattr(self, x))
                for x in "typename value traceback".split()]
        return "<ExcInfoRepr %s>" %(" ".join(l),)

    def exconly(self, tryshort=False):
        """ Somehow crippled version of original one
        """
        return "%s: %s" % (self.typename, self.value)

    def errisinstance(self, exc_t):
        if not isinstance(exc_t, tuple):
            exc_t = (exc_t,)
        for exc in exc_t:
            if self.typename == str(exc).split('.')[-1]:
                return True
        return False

class ReprOutcome(object):
    def __init__(self, repr_tuple):
        (self.passed, self.setupfailure, excinfo, self.skipped,
         self.is_critical, self.signal, self.stdout, self.stderr) = repr_tuple
        if excinfo is None:
            self.excinfo = None
        else:
            self.excinfo = ExcInfoRepr(excinfo)

    def __repr__(self):
        l = ["%s=%s" %(x, getattr(self, x))
                for x in "signal passed skipped setupfailure excinfo stdout stderr".split()]
        return "<ReprOutcome %s>" %(" ".join(l),)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
2chスレッドチェック用ライブラリ

http://www.monazilla.org/index.php?c=6-20

"""
from flask import Flask

import os.path
import urllib2
from StringIO import StringIO
import gzip

config = {'url_pattern': r'http://<server>/<board>/dat/<id>.dat',
          'encoding': 'Shift_JIS',
          'separator': '<>',
          'past_url_patterns': [r'http://<server>/<board>/kako/<id1>/<id2>/<id>.dat.gz',
                                r'http://<server>/<board>/kako/<id1>/<id>.dat.gz']}

"""ヘッダに関しては次のURLを確認。
追加取得をする場合gzipを付与してはいけないことを確認
http://www.monazilla.org/index.php?e=198
"""
httpheaders = {'User-Agent': 'Monazilla/1.00 (py2ch/0.10)'
               'Accept-Encoding': 'gzip',
               'Accept-Language': 'ja',
               'If-Modified-Since': None,
               'If-None-Match': None,
               'Range': None}

def get_root_path():
    try:
        directory = os.path.dirname(__file__)
        return os.path.abspath(directory)
    except AttributeError:

      return os.getcwd()

def urlread(url, headers):
  req = urllib2.Request(url, headers)
  p = urllib2.urlopen(req)
  data = p.read()
  if p.info().get('Content-Encoding') in ('gzip', 'x-gzip'):
    s = StringIO(data)
    z = gzip.GzipFile('rb', fileobj=s)
    data = z.read()
  return data

class ThreadManager(_MetaThreadManagerObject):
  def __init__(self, config, httpheaders):
    url_pattern = config['url_pattern']
    encoding = config['encoding']
    separator = config['separator']
    past_url_patterns = config['past_url_patterns']
    _MetaThreadObject(url_pattern, encoding, seaprator, past_url_patterns)

class _MetaThreadManagerObject(object):
  def __init__(self, url_pattern, encoding, separator, past_url_patterns):
    self.url_pattern = url_pattern
    self.encoding = encoding
    self.separator = separator
    self.past_url_patterns = past_url_patterns
    self.id = None

if __name__ == '__main__':
  print get_root_path()
<commit_msg>implemented urlread function<commit_after># -*- coding: utf-8 -*-
"""
2chスレッドチェック用ライブラリ

http://www.monazilla.org/index.php?c=6-20

"""
from flask import Flask

import os.path
import urllib2
from StringIO import StringIO
import gzip

config = {'url_pattern': r'http://<server>/<board>/dat/<id>.dat',
          'encoding': 'Shift_JIS',
          'separator': '<>',
          'past_url_patterns': [r'http://<server>/<board>/kako/<id1>/<id2>/<id>.dat.gz',
                                r'http://<server>/<board>/kako/<id1>/<id>.dat.gz']}

"""ヘッダに関しては次のURLを確認。
追加取得をする場合gzipを付与してはいけないことを確認
http://www.monazilla.org/index.php?e=198
"""
httpheaders = {'User-Agent': 'Monazilla/1.00 (py2ch/0.10)',
               'Accept-Encoding': 'gzip',
               'Accept-Language': 'ja',
               'If-Modified-Since': None,
               'If-None-Match': None,
               'Range': None}

def get_root_path():
    try:
        directory = os.path.dirname(__file__)
        return os.path.abspath(directory)
    except AttributeError:

      return os.getcwd()

def urlread(url, headers):
  req = urllib2.Request(url, headers=headers)
  p = urllib2.urlopen(req)
  data = p.read()
  info = p.info()
  if p.info().get('Content-Encoding') in ('gzip', 'x-gzip'):
    s = StringIO(data)
    z = gzip.GzipFile('rb', fileobj=s)
    data = z.read()
  return (info, data)

class _MetaThreadManager(object):
  def __init__(self, url_pattern, encoding, separator, past_url_patterns):
    self.url_pattern = url_pattern
    self.encoding = encoding
    self.separator = separator
    self.past_url_patterns = past_url_patterns
    self.id = None

class ThreadManager(_MetaThreadManager):
  def __init__(self, config, httpheaders):
    url_pattern = config['url_pattern']
    encoding = config['encoding']
    separator = config['separator']
    past_url_patterns = config['past_url_patterns']
    _MetaThreadManager.__init__(self, url_pattern, encoding,
                                separator, past_url_patterns)

    self.httpheaders = httpheaders
    self.threads = set()

  def register_threads(self, threads):
    for t in threads:
      self.threads.add(t)

  def fetch_thread_data(self, url):
    info, data = urlread(url, self.httpheaders)
    return info, data.decode(self.encoding, 'ignore')

if __name__ == '__main__':
  threads = ['http://kamome.2ch.net/traf/dat/1310723624.dat',
             'http://kamome.2ch.net/traf/dat/1313507415.dat',
             'http://yuzuru.2ch.net/ftax/dat/1223984982.dat',
             'http://yuzuru.2ch.net/ftax/dat/1196851586.dat']
  tm = ThreadManager(config, httpheaders)
  tm.register_threads(threads)

  for t in tm.threads:
    print "*"*10 + t
    info, data = tm.fetch_thread_data(t)
    print data

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""

Edited by Christian Münker, 2013
"""
import sys
# import EITHER PyQt4 OR PySide, depending on your system
from PyQt4 import QtGui, QtCore
#from PySide.QtCore import *
#from PySide.QtGui import *

import matplotlib as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

import numpy as np
import scipy.signal as sig
import plotAll
#import _plotUtils

import plotAll

N_FFT = 2048 # FFT length for freqz

DEBUG = True

class PlotHf(QtGui.QWidget):
#class plotHf(plotAll.plotAll):

    def __init__(self):
        parent = super(PlotHf, self).__init__()

        self.coeffs = ([1,1,1],[3,0,0]) # dummy definition for notch filter

#    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle('Plot H(f)')
        self.A_SB = 60   # min. Sperrdämpfung im Stoppband in dB (= min. y-Wert des Plots)
#        plotAll.createMPLCanvas(parent)
        self.myCanv = PlotHf.createMPLCanvas(self)
#        self.myCanv = _plotUtils.createMPLCanvas()
        self.update(self.coeffs)

    def createMPLCanvas(self):

        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        self.dpi = 100
        self.pltFig = Figure((5.0, 4.0), dpi=self.dpi)
        self.pltCanv = FigureCanvas(self.pltFig)
        self.pltCanv.setParent(self)

        self.pltAxes = self.pltFig.add_subplot(111)

        # Create the navigation toolbar, tied to the canvas
        #
        self.mpl_toolbar = NavigationToolbar(self.pltCanv, self)

        # SIGNAL & SLOTS
        #
        self.butDraw = QtGui.QPushButton("&Redraw")
        self.butDraw.clicked.connect(self.redraw)

        self.cboxGrid = QtGui.QCheckBox("&Grid")
        self.cboxGrid.setChecked(True)
        # Attention: passes unwanted clicked bool argument:
        self.cboxGrid.clicked.connect(self.redraw)

        lblLw = QtGui.QLabel('Line width:')
        self.sldLw = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.sldLw.setRange(1, 10)
        self.sldLw.setValue(5)
        self.sldLw.setTracking(True)
        self.sldLw.setTickPosition(QtGui.QSlider.NoTicks)
        self.sldLw.valueChanged.connect(self.redraw)

        #=============================================
        # Layout with box sizers
        #=============================================

        hbox1 = QtGui.QHBoxLayout()
        for w in [self.butDraw, self.cboxGrid, lblLw, self.sldLw]:
            hbox1.addWidget(w)
            hbox1.setAlignment(w, QtCore.Qt.AlignVCenter)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.mpl_toolbar)
        vbox.addWidget(self.pltCanv)
        vbox.addLayout(hbox1)
        self.setLayout(vbox)

    def update(self, coeffs):
        """
        Re-calculate |H(f)| and update the figure
        """
        self.coeffs = coeffs
        self.bb = self.coeffs[0]
        self.aa = self.coeffs[1]
        [W,H] = sig.freqz(self.bb, self.aa, N_FFT) # calculate H(W) for W = 0 ... pi
        print
        if DEBUG:
            print("-------------------------")
            print("plotHf.update() ")
            print("-------------------------")
            print("b,a = ", self.bb, self.aa)
        F = W / (2 * np.pi)

        # clear the axes and redraw the plot
        #
        self.pltAxes.clear()
        self.pltAxes.axis([0, 0.5, -self.A_SB-10, 2])

        self.pltPlt, = self.pltAxes.plot(F,20*np.log10(abs(H)),
                       lw = self.sldLw.value())
        self.pltAxes.set_xlabel(r'$F\; \rightarrow $')
        self.pltAxes.set_ylabel(r'$|H(\mathrm{e}^{\mathrm{j} \Omega})|\; \rightarrow $')
        self.pltAxes.set_title(r'Betragsfrequenzgang')
        self.redraw()

    def redraw(self):
        """
        Redraw the figure with new properties (grid, linewidth)
        """
        self.pltAxes.grid(self.cboxGrid.isChecked())
        plt.artist.setp(self.pltPlt, linewidth = self.sldLw.value()/5.)
        self.pltFig.tight_layout()
        self.pltCanv.draw()

#------------------------------------------------------------------------------

def main():
    app = QtGui.QApplication(sys.argv)
    form = PlotHf()
    form.show()
    app.exec_()

if __name__ == "__main__":
    main()
<commit_msg>corrections of parent object<commit_after># -*- coding: utf-8 -*-
"""

Edited by Christian Münker, 2013
"""
import sys
# import EITHER PyQt4 OR PySide, depending on your system
from PyQt4 import QtGui, QtCore
#from PySide.QtCore import *
#from PySide.QtGui import *

import matplotlib as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

import numpy as np
import scipy.signal as sig
#import plotAll.plotAll
#import _plotUtils

#from plotAll import plotAll

N_FFT = 2048 # FFT length for freqz

DEBUG = True

class PlotHf(QtGui.QWidget):
#class PlotHf(plotAll):

    def __init__(self):
        parent = super(PlotHf, self).__init__()

        self.coeffs = ([1,1,1],[3,0,0]) # dummy definition for notch filter

#    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle('Plot H(f)')
        self.A_SB = 60   # min. Sperrdämpfung im Stoppband in dB (= min. y-Wert des Plots)
#        plotAll.createMPLCanvas(parent)
        self.myCanv = PlotHf.createMPLCanvas(self)
#        self.myCanv = _plotUtils.createMPLCanvas()
        self.update(self.coeffs)

    def createMPLCanvas(self):

        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        self.dpi = 100
        self.pltFig = Figure((5.0, 4.0), dpi=self.dpi)
        self.pltCanv = FigureCanvas(self.pltFig)
        self.pltCanv.setParent(self)

        self.pltAxes = self.pltFig.add_subplot(111)

        # Create the navigation toolbar, tied to the canvas
        #
        self.mpl_toolbar = NavigationToolbar(self.pltCanv, self)

        # SIGNAL & SLOTS
        #
        self.butDraw = QtGui.QPushButton("&Redraw")
        self.butDraw.clicked.connect(self.redraw)

        self.cboxGrid = QtGui.QCheckBox("&Grid")
        self.cboxGrid.setChecked(True)
        # Attention: passes unwanted clicked bool argument:
        self.cboxGrid.clicked.connect(self.redraw)

        lblLw = QtGui.QLabel('Line width:')
        self.sldLw = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.sldLw.setRange(1, 10)
        self.sldLw.setValue(5)
        self.sldLw.setTracking(True)
        self.sldLw.setTickPosition(QtGui.QSlider.NoTicks)
        self.sldLw.valueChanged.connect(self.redraw)

        #=============================================
        # Layout with box sizers
        #=============================================

        hbox1 = QtGui.QHBoxLayout()
        for w in [self.butDraw, self.cboxGrid, lblLw, self.sldLw]:
            hbox1.addWidget(w)
            hbox1.setAlignment(w, QtCore.Qt.AlignVCenter)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.mpl_toolbar)
        vbox.addWidget(self.pltCanv)
        vbox.addLayout(hbox1)
        self.setLayout(vbox)

    def update(self, coeffs):
        """
        Re-calculate |H(f)| and update the figure
        """
        self.coeffs = coeffs
        self.bb = self.coeffs[0]
        self.aa = self.coeffs[1]
        [W,H] = sig.freqz(self.bb, self.aa, N_FFT) # calculate H(W) for W = 0 ... pi
        print
        if DEBUG:
            print("-------------------------")
            print("plotHf.update() ")
            print("-------------------------")
            print("b,a = ", self.bb, self.aa)
        F = W / (2 * np.pi)

        # clear the axes and redraw the plot
        #
        self.pltAxes.clear()
        self.pltAxes.axis([0, 0.5, -self.A_SB-10, 2])

        self.pltPlt, = self.pltAxes.plot(F,20*np.log10(abs(H)),
                       lw = self.sldLw.value())
        self.pltAxes.set_xlabel(r'$F\; \rightarrow $')
        self.pltAxes.set_ylabel(r'$|H(\mathrm{e}^{\mathrm{j} \Omega})|\; \rightarrow $')
        self.pltAxes.set_title(r'Betragsfrequenzgang')
        self.redraw()

    def redraw(self):
        """
        Redraw the figure with new properties (grid, linewidth)
        """
        self.pltAxes.grid(self.cboxGrid.isChecked())
        plt.artist.setp(self.pltPlt, linewidth = self.sldLw.value()/5.)
        self.pltFig.tight_layout()
        self.pltCanv.draw()

#------------------------------------------------------------------------------

def main():
    app = QtGui.QApplication(sys.argv)
    form = PlotHf()
    form.show()
    app.exec_()

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before># encoding: utf-8
#
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Author: Kyle Lahnakoski (kyle@lahnakoski.com)
#
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from decimal import Decimal
import math
import __builtin__

from pyLibrary.strings import find_first, _Log
from pyLibrary.dot import Null, coalesce

class Math(object):
    """
    MATH FUNCTIONS THAT ASSUME None IMPLY *NOT APPLICABLE* RATHER THAN *MISSING*
    LET "." BE SOME OPERATOR (+, -, *, etc)
    a.None == None
    None.a == None
    .None == None
    func(None, *kwargs)) == None
    """

    @staticmethod
    def bayesian_add(*args):
        a = args[0]
        if a >= 1 or a <= 0:
            from pyLibrary.debugs.logs import Log
            Log.error("Only allowed values *between* zero and one")

        for b in args[1:]:
            if b == None:
                continue
            if b >= 1 or b <= 0:
                Log.error("Only allowed values *between* zero and one")
            a = a * b / (a * b + (1 - a) * (1 - b))

        return a

    @staticmethod
    def bayesian_subtract(a, b):
        return Math.bayesian_add(a, 1 - b)

    @staticmethod
    def abs(v):
        if v == None:
            return Null
        return abs(v)

    @staticmethod
    def pow(v, expo):
        if v == None:
            return Null
        return math.pow(v, expo)

    @staticmethod
    def exp(v):
        if v == None:
            return Null
        return math.exp(v)

    @staticmethod
    def log(v, base=None):
        try:
            if v == None:
                return Null
            if v == 0.0:
                return -float("inf")
            if base == None:
                return math.log(v)
            return math.log(v, base)
        except Exception, e:
            from pyLibrary.debugs.logs import Log
            Log.error("error in log")

    @staticmethod
    def log10(v):
        try:
            return math.log(v, 10)
        except Exception, e:
            return Null

    # FOR GOODNESS SAKE - IF YOU PROVIDE A METHOD abs(), PLEASE PROVIDE ITS COMPLEMENT
    # x = abs(x)*sign(x)
    # FOUND IN numpy, BUT WE USUALLY DO NOT NEED TO BRING IN A BIG LIB FOR A SIMPLE DECISION
    @staticmethod
    def sign(v):
        if v == None:
            return Null
        if v < 0:
            return -1
        if v > 0:
            return +1
        return 0

    @staticmethod
    def is_number(s):
        if s is True or s is False:
            return False

        try:
            float(s)
            return True
        except Exception:
            return False

    @staticmethod
    def is_finite(s):
        try:
            f = float(s)
            if abs(f) == float("+inf"):
                return False
            return True
        except Exception:
            return False

    @staticmethod
    def is_hex(value):
        try:
            int('00480065006C006C006F00200077006F0072006C00640021', 16)
            return True
        except Exception:
            return False

    @staticmethod
    def is_nan(s):
        return math.isnan(s)

    @staticmethod
    def is_integer(s):
        if s is True or s is False:
            return False

        try:
            if float(s) == round(float(s), 0):
                return True
            return False
        except Exception:
            return False

    @staticmethod
    def round(value, decimal=7, digits=None):
        """
        ROUND TO GIVEN NUMBER OF DIGITS, OR GIVEN NUMBER OF DECIMAL PLACES
        decimal - NUMBER OF SIGNIFICANT DIGITS (LESS THAN 1 IS INVALID)
        digits - NUMBER OF DIGITS AFTER DECIMAL POINT (NEGATIVE IS VALID)
        """
        if value == None:
            return None
        else:
            value = float(value)

        if digits != None:
            if digits <= 0:
                if value == 0:
                    return int(__builtin__.round(value, digits))
                try:
                    m = pow(10, math.ceil(math.log10(abs(value))))
                    return int(__builtin__.round(value / m, digits) * m)
                except Exception, e:
                    from pyLibrary.debugs.logs import Log

                    Log.error("not expected", e)
            else:
                if value == 0:
                    return __builtin__.round(value, digits)
                try:
                    m = pow(10, math.ceil(math.log10(abs(value))))
                    return __builtin__.round(value / m, digits) * m
                except Exception, e:
                    from pyLibrary.debugs.logs import Log
                    Log.error("not expected", e)

        return __builtin__.round(value, decimal)

    @staticmethod
    def floor(value, mod=1):
        """
        x == Math.floor(x, a) + Math.mod(x, a)  FOR ALL a, x
        """
        if value == None:
            return None
        v = int(math.floor(value))
        if v < 0:
            _Log.error("")
        else:
            return v - (v % mod)

    @staticmethod
    def mod(value, mod=1):
        """
        RETURN NON-NEGATIVE VALUE
        """
        if value == None:
            return None
        elif value < 0:
            return value % mod + mod
        else:
            return value % mod

    # RETURN A VALUE CLOSE TO value, BUT WITH SHORTER len(unicode(value))<len(unicode(value)):
    @staticmethod
    def approx_str(value):
        v = unicode(value)
        d = v.find(".")
        if d == -1:
            return value

        if Math.round(value) == value:
            return int(value)

        i = find_first(v, ["9999", "0000"], d)
        if i != -1:
            Math.round(value, decimal=i - d - 1)

        return value

    @staticmethod
    def ceiling(value, mod=1):
        """
        RETURN SMALLEST INTEGER GREATER THAN value
        """
        if value == None:
            return None
        mod = int(mod)

        v = int(math.floor(value + mod))
        return v - (v % mod)

    @staticmethod
    def count(values):
        count = 0
        for v in values:
            if v != None:
                count += 1
        return count

    @staticmethod
    def pow(n, p):
        if n == None or p == None:
            return None
        return math.pow(n, p)

    @staticmethod
    def sum(values):
        sum = 0
        for v in values:
            if v != None:
                sum += v
        return sum

    @staticmethod
    def max(*values):
        return Math.MAX(values)

    @staticmethod
    def MAX(values):
        output = Null
        for v in values:
            if v == None:
                continue
            elif output == None or v > output:
                output = v
            else:
                pass
        return output

    @staticmethod
    def min(*values):
        return Math.MIN(values)

    @staticmethod
    def MIN(values):
        output = None
        for v in values:
            if v == None:
                continue
            elif output == None or v < output:
                output = v
            else:
                pass
        return output

    @staticmethod
    def range(start, stop, interval):
        i = start
        while i<stop:
            yield i
            i+=interval

def almost_equal(first, second, digits=None, places=None, delta=None):
    if first == second:
        return True

    if delta is not None:
        if abs(first - second) <= delta:
            return True
    else:
        places = coalesce(places, digits, 18)
        diff = math.log10(abs(first-second))
        if diff < Math.ceiling(math.log10(first))-places:
            return True

    return False

<commit_msg>fix mod<commit_after># encoding: utf-8
#
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Author: Kyle Lahnakoski (kyle@lahnakoski.com)
#
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from decimal import Decimal
import math
import __builtin__

from pyLibrary.strings import find_first, _Log
from pyLibrary.dot import Null, coalesce

class Math(object):
    """
    MATH FUNCTIONS THAT ASSUME None IMPLY *NOT APPLICABLE* RATHER THAN *MISSING*
    LET "." BE SOME OPERATOR (+, -, *, etc)
    a.None == None
    None.a == None
    .None == None
    func(None, *kwargs)) == None
    """

    @staticmethod
    def bayesian_add(*args):
        a = args[0]
        if a >= 1 or a <= 0:
            from pyLibrary.debugs.logs import Log
            Log.error("Only allowed values *between* zero and one")

        for b in args[1:]:
            if b == None:
                continue
            if b >= 1 or b <= 0:
                Log.error("Only allowed values *between* zero and one")
            a = a * b / (a * b + (1 - a) * (1 - b))

        return a

    @staticmethod
    def bayesian_subtract(a, b):
        return Math.bayesian_add(a, 1 - b)

    @staticmethod
    def abs(v):
        if v == None:
            return Null
        return abs(v)

    @staticmethod
    def pow(v, expo):
        if v == None:
            return Null
        return math.pow(v, expo)

    @staticmethod
    def exp(v):
        if v == None:
            return Null
        return math.exp(v)

    @staticmethod
    def log(v, base=None):
        try:
            if v == None:
                return Null
            if v == 0.0:
                return -float("inf")
            if base == None:
                return math.log(v)
            return math.log(v, base)
        except Exception, e:
            from pyLibrary.debugs.logs import Log
            Log.error("error in log")

    @staticmethod
    def log10(v):
        try:
            return math.log(v, 10)
        except Exception, e:
            return Null

    # FOR GOODNESS SAKE - IF YOU PROVIDE A METHOD abs(), PLEASE PROVIDE ITS COMPLEMENT
    # x = abs(x)*sign(x)
    # FOUND IN numpy, BUT WE USUALLY DO NOT NEED TO BRING IN A BIG LIB FOR A SIMPLE DECISION
    @staticmethod
    def sign(v):
        if v == None:
            return Null
        if v < 0:
            return -1
        if v > 0:
            return +1
        return 0

    @staticmethod
    def is_number(s):
        if s is True or s is False:
            return False

        try:
            float(s)
            return True
        except Exception:
            return False

    @staticmethod
    def is_finite(s):
        try:
            f = float(s)
            if abs(f) == float("+inf"):
                return False
            return True
        except Exception:
            return False

    @staticmethod
    def is_hex(value):
        try:
            int('00480065006C006C006F00200077006F0072006C00640021', 16)
            return True
        except Exception:
            return False

    @staticmethod
    def is_nan(s):
        return math.isnan(s)

    @staticmethod
    def is_integer(s):
        if s is True or s is False:
            return False

        try:
            if float(s) == round(float(s), 0):
                return True
            return False
        except Exception:
            return False

    @staticmethod
    def round(value, decimal=7, digits=None):
        """
        ROUND TO GIVEN NUMBER OF DIGITS, OR GIVEN NUMBER OF DECIMAL PLACES
        decimal - NUMBER OF SIGNIFICANT DIGITS (LESS THAN 1 IS INVALID)
        digits - NUMBER OF DIGITS AFTER DECIMAL POINT (NEGATIVE IS VALID)
        """
        if value == None:
            return None
        else:
            value = float(value)

        if digits != None:
            if digits <= 0:
                if value == 0:
                    return int(__builtin__.round(value, digits))
                try:
                    m = pow(10, math.ceil(math.log10(abs(value))))
                    return int(__builtin__.round(value / m, digits) * m)
                except Exception, e:
                    from pyLibrary.debugs.logs import Log

                    Log.error("not expected", e)
            else:
                if value == 0:
                    return __builtin__.round(value, digits)
                try:
                    m = pow(10, math.ceil(math.log10(abs(value))))
                    return __builtin__.round(value / m, digits) * m
                except Exception, e:
                    from pyLibrary.debugs.logs import Log
                    Log.error("not expected", e)

        return __builtin__.round(value, decimal)

    @staticmethod
    def floor(value, mod=1):
        """
        x == Math.floor(x, a) + Math.mod(x, a)  FOR ALL a, x
        """
        if value == None:
            return None
        v = int(math.floor(value))
        if v < 0:
            _Log.error("")
        else:
            return v - (v % mod)

    @staticmethod
    def mod(value, mod=1):
        """
        RETURN NON-NEGATIVE VALUE
        """
        if value == None:
            return None
        elif value < 0:
            return (value % mod + mod) % mod
        else:
            return value % mod

    # RETURN A VALUE CLOSE TO value, BUT WITH SHORTER len(unicode(value))<len(unicode(value)):
    @staticmethod
    def approx_str(value):
        v = unicode(value)
        d = v.find(".")
        if d == -1:
            return value

        if Math.round(value) == value:
            return int(value)

        i = find_first(v, ["9999", "0000"], d)
        if i != -1:
            Math.round(value, decimal=i - d - 1)

        return value

    @staticmethod
    def ceiling(value, mod=1):
        """
        RETURN SMALLEST INTEGER GREATER THAN value
        """
        if value == None:
            return None
        mod = int(mod)

        v = int(math.floor(value + mod))
        return v - (v % mod)

    @staticmethod
    def count(values):
        count = 0
        for v in values:
            if v != None:
                count += 1
        return count

    @staticmethod
    def pow(n, p):
        if n == None or p == None:
            return None
        return math.pow(n, p)

    @staticmethod
    def sum(values):
        sum = 0
        for v in values:
            if v != None:
                sum += v
        return sum

    @staticmethod
    def max(*values):
        return Math.MAX(values)

    @staticmethod
    def MAX(values):
        output = Null
        for v in values:
            if v == None:
                continue
            elif output == None or v > output:
                output = v
            else:
                pass
        return output

    @staticmethod
    def min(*values):
        return Math.MIN(values)

    @staticmethod
    def MIN(values):
        output = None
        for v in values:
            if v == None:
                continue
            elif output == None or v < output:
                output = v
            else:
                pass
        return output

    @staticmethod
    def range(start, stop, interval):
        i = start
        while i<stop:
            yield i
            i+=interval

def almost_equal(first, second, digits=None, places=None, delta=None):
    if first == second:
        return True

    if delta is not None:
        if abs(first - second) <= delta:
            return True
    else:
        places = coalesce(places, digits, 18)
        diff = math.log10(abs(first-second))
        if diff < Math.ceiling(math.log10(first))-places:
            return True

    return False

<|endoftext|>


<commit_before>"""
@author: Pranay Pradhananga, Damian Katsigiannis
@filename: ExpressionLayout.py
@title: ExpressionLayout
@description: This is the main program for the Scratchbasic application.
              It consists of four major layout panel: Main Layout, Command Panel Layout, Workspace Layout, Output Layout
              MainLayout is the base layout that instantiates Command Panel, Workspace and Output layout in order
              Each Expression Layout PRINT, LET, IF/GOTO, GOTO is a subclass of Expression Layout
              Such design consideration allows one to add a new expression by simply extending Expression Layout
              This program reuses existing Dumbasic program written in Python to compute the expressions and operations
              An instance of Interpreter class is used to integrate with Dumbasic program
"""

import kivy

from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from Layouts.Expressions.ExpressionLayout import ExpressionLayout

kivy.require('1.0.6') # current kivy version !

class IfLayout(ExpressionLayout):

    def __init__(self, line, var_list=[], **kwargs):
        super(IfLayout, self).__init__(line, "IF", var_list,  **kwargs)

        self.cols = 9
        self.padding = 4
        self.height = 40
        self.width = 380

        ## create buttons for each variable names
        #for var in var_list:
        #    self.btn_variables.append(Button(text = str.strip(str(var)),size_hint_y=None,height=40))

        ## add the buttons of variables as options for Combo edit
        #self.txt_value1 = ComboEdit( size_hint= (.1, 1), height=50, options=self.btn_variables)

        #self.txt_value1 = TextInput(multiline = False, size_hint=(.1,1))
        self.txt_value1 = self.cmb_variables
        self.spn_operator = Spinner(text = '==', values =('>', '<', '=='), size_hint=(.1,1))
        self.txt_value2 = TextInput(multiline = False, size_hint=(.1,1))
        self.lbl_goto = Label(text="GOTO", size_hint=(.1,1))
        self.txt_value3 = TextInput(multiline = False, size_hint=(.1,1))

    """
    Add the widgets to the layout
    """
    def draw(self):
        super(IfLayout, self).draw()
        self.add_widget(self.txt_value1)
        self.add_widget(self.spn_operator)
        self.add_widget(self.txt_value2)
        self.add_widget(self.lbl_goto)
        self.add_widget(self.txt_value3)

    """
    Get the expression list
    """
    def get_expression(self):
        super(IfLayout, self).get_expression()
        if str(self.txt_value3.text.isdigit()):
            return [self.name, str(self.txt_value1.text), self.spn_operator.text, str(self.txt_value2.text), self.lbl_goto.text, str(self.txt_value3.text)]
        else:
            return ["Error", "Line number is not valid"]

<commit_msg>Fixed a bug with variable names to strip spaces"<commit_after>"""
@author: Pranay Pradhananga, Damian Katsigiannis
@filename: ExpressionLayout.py
@title: ExpressionLayout
@description: This is the main program for the Scratchbasic application.
              It consists of four major layout panel: Main Layout, Command Panel Layout, Workspace Layout, Output Layout
              MainLayout is the base layout that instantiates Command Panel, Workspace and Output layout in order
              Each Expression Layout PRINT, LET, IF/GOTO, GOTO is a subclass of Expression Layout
              Such design consideration allows one to add a new expression by simply extending Expression Layout
              This program reuses existing Dumbasic program written in Python to compute the expressions and operations
              An instance of Interpreter class is used to integrate with Dumbasic program
"""

import kivy

from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from Layouts.Expressions.ExpressionLayout import ExpressionLayout

kivy.require('1.0.6') # current kivy version !

class IfLayout(ExpressionLayout):

    def __init__(self, line, var_list=[], **kwargs):
        super(IfLayout, self).__init__(line, "IF", var_list,  **kwargs)

        self.cols = 9
        self.padding = 4
        self.height = 40
        self.width = 380

        self.txt_value1 = self.cmb_variables
        self.spn_operator = Spinner(text = '==', values =('>', '<', '=='), size_hint=(.1,1))
        self.txt_value2 = TextInput(multiline = False, size_hint=(.1,1))
        self.lbl_goto = Label(text="GOTO", size_hint=(.1,1))
        self.txt_value3 = TextInput(multiline = False, size_hint=(.1,1))

    """
    Add the widgets to the layout
    """
    def draw(self):
        super(IfLayout, self).draw()
        self.add_widget(self.txt_value1)
        self.add_widget(self.spn_operator)
        self.add_widget(self.txt_value2)
        self.add_widget(self.lbl_goto)
        self.add_widget(self.txt_value3)

    """
    Get the expression list
    """
    def get_expression(self):
        super(IfLayout, self).get_expression()
        if str(self.txt_value3.text.isdigit()):
            return [self.name, str(self.txt_value1.text), self.spn_operator.text, str(self.txt_value2.text), self.lbl_goto.text, str(self.txt_value3.text)]
        else:
            return ["Error", "Line number is not valid"]

<|endoftext|>