<commit_before>"""Zwave discovery schemas."""
from . import const

DEFAULT_VALUES_SCHEMA = {
    'power': {
        const.DISC_SCHEMAS: [
            {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_POWER]},
            {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_METER],
             const.DISC_INDEX: [const.INDEX_METER_POWER]},
            ],
        const.DISC_OPTIONAL: True,
        },
}

DISCOVERY_SCHEMAS = [
    {const.DISC_COMPONENT: 'binary_sensor',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_ENTRY_CONTROL,
         const.GENERIC_TYPE_SENSOR_ALARM,
         const.GENERIC_TYPE_SENSOR_BINARY,
         const.GENERIC_TYPE_SWITCH_BINARY,
         const.GENERIC_TYPE_METER,
         const.GENERIC_TYPE_SENSOR_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SENSOR_NOTIFICATION,
         const.GENERIC_TYPE_THERMOSTAT],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_BINARY],
             const.DISC_TYPE: const.TYPE_BOOL,
             const.DISC_GENRE: const.GENRE_USER,
         },
         'off_delay': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [9],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'climate',
     const.DISC_GENERIC_DEVICE_CLASS: [const.GENERIC_TYPE_THERMOSTAT],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_SETPOINT],
         },
         'temperature': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_TEMPERATURE],
             const.DISC_OPTIONAL: True,
         },
         'mode': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_THERMOSTAT_MODE],
             const.DISC_OPTIONAL: True,
         },
         'fan_mode': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_FAN_MODE],
             const.DISC_OPTIONAL: True,
         },
         'operating_state': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_OPERATING_STATE],
             const.DISC_OPTIONAL: True,
         },
         'fan_state': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_FAN_STATE],
             const.DISC_OPTIONAL: True,
         },
         'zxt_120_swing_mode': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [33],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Rollershutter
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_GENRE: const.GENRE_USER,
         },
         'open': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_BRIGHT],
             const.DISC_OPTIONAL: True,
         },
         'close': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DIM],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Garage Door Switch
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_BINARY],
             const.DISC_GENRE: const.GENRE_USER,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Garage Door Barrier
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_BARRIER_OPERATOR],
             const.DISC_INDEX: [const.INDEX_BARRIER_OPERATOR_LABEL],
         }})},
    {const.DISC_COMPONENT: 'fan',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_FAN_SWITCH],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_LEVEL],
             const.DISC_TYPE: const.TYPE_BYTE,
         }})},
    {const.DISC_COMPONENT: 'light',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_REMOTE],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL,
         const.SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL,
         const.SPECIFIC_TYPE_NOT_USED],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_LEVEL],
             const.DISC_TYPE: const.TYPE_BYTE,
         },
         'dimming_duration': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DURATION],
             const.DISC_OPTIONAL: True,
         },
         'color': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR],
             const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_COLOR],
             const.DISC_OPTIONAL: True,
         },
         'color_channels': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR],
             const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_CHANNELS],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'lock',
     const.DISC_GENERIC_DEVICE_CLASS: [const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_ADVANCED_DOOR_LOCK,
         const.SPECIFIC_TYPE_SECURE_KEYPAD_DOOR_LOCK,
         const.SPECIFIC_TYPE_SECURE_LOCKBOX],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_DOOR_LOCK],
             const.DISC_INDEX: [const.INDEX_DOOR_LOCK_LOCK],
         },
         'access_control': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_ACCESS_CONTROL],
             const.DISC_OPTIONAL: True,
         },
         'alarm_type': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_TYPE],
             const.DISC_OPTIONAL: True,
         },
         'alarm_level': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_LEVEL],
             const.DISC_OPTIONAL: True,
         },
         'v2btze_advanced': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [12],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'sensor',
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_SENSOR_MULTILEVEL,
                 const.COMMAND_CLASS_METER,
                 const.COMMAND_CLASS_ALARM,
                 const.COMMAND_CLASS_SENSOR_ALARM],
             const.DISC_GENRE: const.GENRE_USER,
         }})},
    {const.DISC_COMPONENT: 'switch',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_METER,
         const.GENERIC_TYPE_SENSOR_ALARM,
         const.GENERIC_TYPE_SENSOR_BINARY,
         const.GENERIC_TYPE_SWITCH_BINARY,
         const.GENERIC_TYPE_ENTRY_CONTROL,
         const.GENERIC_TYPE_SENSOR_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SENSOR_NOTIFICATION,
         const.GENERIC_TYPE_GENERIC_CONTROLLER,
         const.GENERIC_TYPE_SWITCH_REMOTE,
         const.GENERIC_TYPE_REPEATER_SLAVE,
         const.GENERIC_TYPE_THERMOSTAT,
         const.GENERIC_TYPE_WALL_CONTROLLER],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_BINARY],
             const.DISC_TYPE: const.TYPE_BOOL,
             const.DISC_GENRE: const.GENRE_USER,
         }})},
]
<commit_msg>Make RS room thermostat discoverable (#15451)<commit_after>"""Zwave discovery schemas."""
from . import const

DEFAULT_VALUES_SCHEMA = {
    'power': {
        const.DISC_SCHEMAS: [
            {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_POWER]},
            {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_METER],
             const.DISC_INDEX: [const.INDEX_METER_POWER]},
            ],
        const.DISC_OPTIONAL: True,
        },
}

DISCOVERY_SCHEMAS = [
    {const.DISC_COMPONENT: 'binary_sensor',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_ENTRY_CONTROL,
         const.GENERIC_TYPE_SENSOR_ALARM,
         const.GENERIC_TYPE_SENSOR_BINARY,
         const.GENERIC_TYPE_SWITCH_BINARY,
         const.GENERIC_TYPE_METER,
         const.GENERIC_TYPE_SENSOR_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SENSOR_NOTIFICATION,
         const.GENERIC_TYPE_THERMOSTAT],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_BINARY],
             const.DISC_TYPE: const.TYPE_BOOL,
             const.DISC_GENRE: const.GENRE_USER,
         },
         'off_delay': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [9],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'climate',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_THERMOSTAT,
         const.GENERIC_TYPE_SENSOR_MULTILEVEL],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_SETPOINT],
         },
         'temperature': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_TEMPERATURE],
             const.DISC_OPTIONAL: True,
         },
         'mode': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_THERMOSTAT_MODE],
             const.DISC_OPTIONAL: True,
         },
         'fan_mode': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_FAN_MODE],
             const.DISC_OPTIONAL: True,
         },
         'operating_state': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_OPERATING_STATE],
             const.DISC_OPTIONAL: True,
         },
         'fan_state': {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_THERMOSTAT_FAN_STATE],
             const.DISC_OPTIONAL: True,
         },
         'zxt_120_swing_mode': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [33],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Rollershutter
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_GENRE: const.GENRE_USER,
         },
         'open': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_BRIGHT],
             const.DISC_OPTIONAL: True,
         },
         'close': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DIM],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Garage Door Switch
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_BINARY],
             const.DISC_GENRE: const.GENRE_USER,
         }})},
    {const.DISC_COMPONENT: 'cover',  # Garage Door Barrier
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL,
         const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION,
         const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON,
         const.SPECIFIC_TYPE_SECURE_DOOR],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_BARRIER_OPERATOR],
             const.DISC_INDEX: [const.INDEX_BARRIER_OPERATOR_LABEL],
         }})},
    {const.DISC_COMPONENT: 'fan',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_FAN_SWITCH],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_LEVEL],
             const.DISC_TYPE: const.TYPE_BYTE,
         }})},
    {const.DISC_COMPONENT: 'light',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_REMOTE],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL,
         const.SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL,
         const.SPECIFIC_TYPE_NOT_USED],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_LEVEL],
             const.DISC_TYPE: const.TYPE_BYTE,
         },
         'dimming_duration': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL],
             const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DURATION],
             const.DISC_OPTIONAL: True,
         },
         'color': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR],
             const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_COLOR],
             const.DISC_OPTIONAL: True,
         },
         'color_channels': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR],
             const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_CHANNELS],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'lock',
     const.DISC_GENERIC_DEVICE_CLASS: [const.GENERIC_TYPE_ENTRY_CONTROL],
     const.DISC_SPECIFIC_DEVICE_CLASS: [
         const.SPECIFIC_TYPE_ADVANCED_DOOR_LOCK,
         const.SPECIFIC_TYPE_SECURE_KEYPAD_DOOR_LOCK,
         const.SPECIFIC_TYPE_SECURE_LOCKBOX],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_DOOR_LOCK],
             const.DISC_INDEX: [const.INDEX_DOOR_LOCK_LOCK],
         },
         'access_control': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_ACCESS_CONTROL],
             const.DISC_OPTIONAL: True,
         },
         'alarm_type': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_TYPE],
             const.DISC_OPTIONAL: True,
         },
         'alarm_level': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM],
             const.DISC_INDEX: [const.INDEX_ALARM_LEVEL],
             const.DISC_OPTIONAL: True,
         },
         'v2btze_advanced': {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION],
             const.DISC_INDEX: [12],
             const.DISC_OPTIONAL: True,
         }})},
    {const.DISC_COMPONENT: 'sensor',
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [
                 const.COMMAND_CLASS_SENSOR_MULTILEVEL,
                 const.COMMAND_CLASS_METER,
                 const.COMMAND_CLASS_ALARM,
                 const.COMMAND_CLASS_SENSOR_ALARM],
             const.DISC_GENRE: const.GENRE_USER,
         }})},
    {const.DISC_COMPONENT: 'switch',
     const.DISC_GENERIC_DEVICE_CLASS: [
         const.GENERIC_TYPE_METER,
         const.GENERIC_TYPE_SENSOR_ALARM,
         const.GENERIC_TYPE_SENSOR_BINARY,
         const.GENERIC_TYPE_SWITCH_BINARY,
         const.GENERIC_TYPE_ENTRY_CONTROL,
         const.GENERIC_TYPE_SENSOR_MULTILEVEL,
         const.GENERIC_TYPE_SWITCH_MULTILEVEL,
         const.GENERIC_TYPE_SENSOR_NOTIFICATION,
         const.GENERIC_TYPE_GENERIC_CONTROLLER,
         const.GENERIC_TYPE_SWITCH_REMOTE,
         const.GENERIC_TYPE_REPEATER_SLAVE,
         const.GENERIC_TYPE_THERMOSTAT,
         const.GENERIC_TYPE_WALL_CONTROLLER],
     const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{
         const.DISC_PRIMARY: {
             const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_BINARY],
             const.DISC_TYPE: const.TYPE_BOOL,
             const.DISC_GENRE: const.GENRE_USER,
         }})},
]
<|endoftext|>


<commit_before># Copyright 2017 Onestein (<http://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models

class HrHolidaysStatus(models.Model):
    _inherit = "hr.holidays.status"

    holiday_ids = fields.One2many(
        'hr.holidays',
        'holiday_status_id',
        string='Holidays'
    )

    @api.model
    def _check_init_dict(self, employee_id, res):
        if employee_id not in res:
            res[employee_id] = {
                'consumed_leaves': 0.0,
                'amount_counter': 0.0,
                'amount_partial_consumed': 0.0,
                'allocations_partial_consumed': self.env['hr.holidays'],
                'allocations_not_consumed': self.env['hr.holidays'],
                'allocations_consumed': self.env['hr.holidays'],
            }

    @api.multi
    def _set_consumed_leaves(self, res):
        self.ensure_one()
        for leave in self.holiday_ids.filtered(
            lambda r: r.type == 'remove' and r.state in [
                'confirm', 'validate1', 'validate']):
            employee_id = leave.employee_id.id
            self._check_init_dict(employee_id, res)
            consumed_leaves = leave._get_duration()
            res[employee_id]['consumed_leaves'] += consumed_leaves

    @api.multi
    def _set_consumed_allocations(self, res):
        self.ensure_one()
        for allocation in self.holiday_ids.filtered(
            lambda r: r.type == 'add' and
                r.state in ['confirm', 'validate1', 'validate']
        ).sorted(key=lambda r: r.expiration_date or ''):
            self._set_data_from_consumed_allocation(allocation, res)

    @api.model
    def _set_data_from_consumed_allocation(self, allocation, res):
        employee_id = allocation.employee_id.id
        allocated_amount = allocation._get_duration()
        self._check_init_dict(employee_id, res)
        if res[employee_id]['amount_counter'] + allocated_amount > \
                res[employee_id]['consumed_leaves']:
            if res[employee_id]['amount_counter'] < res[employee_id]['consumed_leaves']:
                amount_partial_consumed = res[employee_id]['amount_counter'] + \
                                          allocated_amount - res[employee_id]['consumed_leaves']
                res[employee_id]['amount_partial_consumed'] = amount_partial_consumed
                res[employee_id]['allocations_partial_consumed'] += allocation
            else:
                res[employee_id]['allocations_not_consumed'] += allocation
        else:
            res[employee_id]['allocations_consumed'] += allocation
        res[employee_id]['amount_counter'] += allocated_amount

    @api.multi
    def _compute_consumed_allocations(self):
        self.ensure_one()
        res = {}
        self._set_consumed_leaves(res)
        self._set_consumed_allocations(res)
        return res

    @api.multi
    def toggle_active(self):
        for record in self:
            if record.active and not record.limit:
                view = self.env.ref(
                    'hr_holidays_expiration.wizard_hr_holidays_status_archive'
                )

                return {
                    'type': 'ir.actions.act_window',
                    'name': _('Close Holidays Status'),
                    'view_mode': 'form',
                    'res_model': 'wizard.hr.holidays.status.archive',
                    'target': 'new',
                    'views': [[view.id, 'form']],
                }

        return super(HrHolidaysStatus, self).toggle_active()
<commit_msg>Flake8 hr_holidays_expiration<commit_after># Copyright 2017 Onestein (<http://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models

class HrHolidaysStatus(models.Model):
    _inherit = "hr.holidays.status"

    holiday_ids = fields.One2many(
        'hr.holidays',
        'holiday_status_id',
        string='Holidays'
    )

    @api.model
    def _check_init_dict(self, employee_id, res):
        if employee_id not in res:
            res[employee_id] = {
                'consumed_leaves': 0.0,
                'amount_counter': 0.0,
                'amount_partial_consumed': 0.0,
                'allocations_partial_consumed': self.env['hr.holidays'],
                'allocations_not_consumed': self.env['hr.holidays'],
                'allocations_consumed': self.env['hr.holidays'],
            }

    @api.multi
    def _set_consumed_leaves(self, res):
        self.ensure_one()
        for leave in self.holiday_ids.filtered(
            lambda r: r.type == 'remove' and r.state in [
                'confirm', 'validate1', 'validate']):
            employee_id = leave.employee_id.id
            self._check_init_dict(employee_id, res)
            consumed_leaves = leave._get_duration()
            res[employee_id]['consumed_leaves'] += consumed_leaves

    @api.multi
    def _set_consumed_allocations(self, res):
        self.ensure_one()
        for allocation in self.holiday_ids.filtered(
            lambda r: r.type == 'add' and
                r.state in ['confirm', 'validate1', 'validate']
        ).sorted(key=lambda r: r.expiration_date or ''):
            self._set_data_from_consumed_allocation(allocation, res)

    @api.model
    def _set_data_from_consumed_allocation(self, allocation, res):
        employee_id = allocation.employee_id.id
        allocated_amount = allocation._get_duration()
        self._check_init_dict(employee_id, res)
        if res[employee_id]['amount_counter'] + allocated_amount > \
                res[employee_id]['consumed_leaves']:
            if res[employee_id]['amount_counter'] < res[employee_id]['consumed_leaves']:
                amount_partial_consumed = res[employee_id]['amount_counter'] + \
                    allocated_amount - res[employee_id]['consumed_leaves']
                res[employee_id]['amount_partial_consumed'] = amount_partial_consumed
                res[employee_id]['allocations_partial_consumed'] += allocation
            else:
                res[employee_id]['allocations_not_consumed'] += allocation
        else:
            res[employee_id]['allocations_consumed'] += allocation
        res[employee_id]['amount_counter'] += allocated_amount

    @api.multi
    def _compute_consumed_allocations(self):
        self.ensure_one()
        res = {}
        self._set_consumed_leaves(res)
        self._set_consumed_allocations(res)
        return res

    @api.multi
    def toggle_active(self):
        for record in self:
            if record.active and not record.limit:
                view = self.env.ref(
                    'hr_holidays_expiration.wizard_hr_holidays_status_archive'
                )

                return {
                    'type': 'ir.actions.act_window',
                    'name': _('Close Holidays Status'),
                    'view_mode': 'form',
                    'res_model': 'wizard.hr.holidays.status.archive',
                    'target': 'new',
                    'views': [[view.id, 'form']],
                }

        return super(HrHolidaysStatus, self).toggle_active()
<|endoftext|>


<commit_before>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2010-2013, GEM foundation

#  OpenQuake is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Affero General Public License as published
#  by the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  OpenQuake is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

"""
A script to dump hazard outputs. If you launch it with a hazard_calculation_id
it will dump all the hazard outputs relevant for risk calculations in a
zip file named hc<hazard-calculation-id>.zip. The zip file can then be
moved around and restored in a different database. Just unzip it and
follow the instructions in the README.txt file, i.e. run the included
restore.sh file. Internally the dump and restore procedures are based on
COPY TO and COPY FROM commands, so they are quite performant even for
large datasets. They could trivially be extended to perform binary
dump/restore, if needed.
"""

import os
import shutil
import zipfile
import argparse
from django.db import connection

README = '''\
To restore a hazard computation and all of its outputs into a new database,
follow this procedure.

1. go in the directory where this README is
2. run ``source restore.sh``

The restore may fail if your database already contains a hazard calculation
with the same id. If you think that the hazard calculation on your database
is not important and can removed together with all of its outputs, then
remove it by using ``bin/openquake --delete-hazard-calculation`` (which
must be run by an user with sufficient permissions). Then run again
``source restore.sh``.
'''

def tuplestr(row):
    return '(%s)' % ', '.join(str(x) for x in row)

class Cursor(object):
    """
    Small wrapper around a psycopg2 cursor
    """
    def __init__(self, psycopg2_cursor):
        self._cursor = psycopg2_cursor

    def tuplestr(self, query, *args):
        "Retrieve tuples of ids a strings"
        self._cursor.execute(query, args)
        return tuplestr(row[0] for row in self._cursor)

    def fetchall(self, query, *args):
        "Dispatch to .fetchall"
        self._cursor.execute(query, args)
        return self._cursor.fetchall()

    def copy(self, query, dest, name, mode):
        """
        Performs a COPY TO/FROM operation; sql is the query, dest
        is the destination directory, name is the destination name
        and mode is 'w' (for COPY TO) or 'r' (for COPY FROM).
        """
        fname = os.path.join(dest, name)
        print '%s (-> %s)' % (query, fname)
        with open(fname, mode) as f:
            self._cursor.copy_expert(query, f)

def zipdir(dirpath):
    "zip the contents of a directory in a zipfile and remove the directory"
    with zipfile.ZipFile(dirpath + '.zip', 'w') as z:
        for name in os.listdir(dirpath):
            z.write(os.path.join(dirpath, name))
    shutil.rmtree(dirpath)
    return dirpath + '.zip'

def restore_cmd(*names):
    'Return a list of COPY FROM commands'
    return ["COPY %s FROM 'PWD/%s.csv';\n" % (name, name.split('.')[-1])
            for name in names]

def dump_hazard_calculation(curs, id_, dest):
    curs.copy("""copy (select * from uiapi.hazard_calculation where id=%s)
              to stdout""" % id_, dest, 'hazard_calculation.csv', 'w')
    curs.copy("""copy (select * from hzrdr.lt_realization
              where hazard_calculation_id=%s)
              to stdout""" % id_, dest, 'lt_realization.csv', 'w')
    return restore_cmd('uiapi.hazard_calculation', 'hzrdr.lt_realization')

def dump_oq_job(curs, id_, dest):
    curs.copy("""copy (select * from uiapi.oq_job where id in %s)
              to stdout""" % id_, dest, 'oq_job.csv', 'w')
    return restore_cmd('uiapi.oq_job')

def dump_output(curs, ids, dest):
    curs.copy("""copy (select * from uiapi.output where id in %s)
              to stdout""" % ids, dest, 'output.csv', 'w')
    return restore_cmd('uiapi.output')

def dump_hazard_curve(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.hazard_curve where output_id in %s)
              to stdout""" % output, dest, 'hazard_curve.csv', 'w')

    ids = curs.tuplestr(
        'select id from hzrdr.hazard_curve where output_id in %s' % output)
    curs.copy("""copy (select * from hzrdr.hazard_curve_data
              where hazard_curve_id in {})
              to stdout""".format(ids), dest, 'hazard_curve_data.csv', 'w')

    return restore_cmd('hzrdr.hazard_curve', 'hzrdr.hazard_curve_data')

def dump_gmf_collection(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.gmf_collection
              where output_id in %s)
              to stdout""" % output, dest, 'gmf_collection.csv', 'w')

    coll_ids = curs.tuplestr('select id from hzrdr.gmf_collection '
                             'where output_id in %s' % output)
    curs.copy("""copy (select * from hzrdr.gmf_set
              where gmf_collection_id in %s)
              to stdout""" % coll_ids, dest, 'gmf_set.csv', 'w')

    set_ids = curs.tuplestr('select id from hzrdr.gmf_set '
                            'where gmf_collection_id in %s' % coll_ids)
    curs.copy("""copy (select * from hzrdr.gmf where gmf_set_id in {})
              to stdout""".format(set_ids), dest, 'gmf.csv', 'w')

    return restore_cmd('hzrdr.gmf_collection', 'hzrdr.gmf_set', 'hzrdr.gmf')

def dump_gmf_scenario(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.gmf_scenario
                 where output_id in %s)
                 to stdout""" % output, dest, 'gmf_scenario.csv', 'w')
    return restore_cmd('hzrdr.gmf_scenario')

def main(hazard_calculation_id):
    """
    Dump a hazard_calculation and its relative outputs.
    """
    out_dir = 'hc%s' % hazard_calculation_id
    if os.path.exists(out_dir):
        shutil.rmtree(out_dir)
    os.mkdir(out_dir)

    curs = Cursor(connection.cursor().cursor.cursor)

    jobs = curs.tuplestr(
        'select id from uiapi.oq_job where hazard_calculation_id =%s',
        hazard_calculation_id)

    outputs = curs.fetchall("""\
    select output_type, array_agg(id) from uiapi.output
    where oq_job_id in %s group by output_type
    having output_type in ('gmf', 'hazard_curve', 'gmf_scenario')
       """ % jobs)
    if not outputs:
        raise SystemExit('No outputs for jobs %s' % jobs)
    restore = dump_hazard_calculation(curs, hazard_calculation_id, out_dir)
    restore.extend(dump_oq_job(curs, jobs, out_dir))
    all_outs = sum([output_ids for output_type, output_ids in outputs], [])
    restore.extend(dump_output(curs, tuplestr(all_outs), out_dir))
    for output_type, output_ids in outputs:
        ids = tuplestr(output_ids)
        if output_type == 'hazard_curve':
            restore.extend(dump_hazard_curve(curs, ids, out_dir))
        elif output_type == 'gmf':
            restore.extend(dump_gmf_collection(curs, ids, out_dir))
        elif output_type == 'gmf_scenario':
            restore.extend(dump_gmf_scenario(curs, ids, out_dir))

    restore_script = os.path.join(out_dir, 'restore.sql')
    with open(restore_script, 'w') as f:
        for cmd in restore:
            f.write(cmd)
    with open(os.path.join(out_dir, 'restore.sh'), 'w') as f:
        f.write('sed -ie "s@PWD@`pwd`@g" restore.sql\n')
        f.write('psql openquake -f restore.sql\n')
    with open(os.path.join(out_dir, 'README.txt'), 'w') as f:
        f.write(README)
    print 'Written %s' % zipdir(out_dir)

if __name__ == '__main__':
    p = argparse.ArgumentParser()
    p.add_argument('hazard_calculation_id')
    arg = p.parse_args()
    main(arg.hazard_calculation_id)
<commit_msg>Fixed a comment<commit_after>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2013, GEM Foundation

#  OpenQuake is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Affero General Public License as published
#  by the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  OpenQuake is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

"""
A script to dump hazard outputs. If you launch it with a hazard_calculation_id
it will dump all the hazard outputs relevant for risk calculations in a
zip file named hc<hazard-calculation-id>.zip. The zip file can then be
moved around and restored in a different database. Just unzip it and
follow the instructions in the README.txt file, i.e. run the included
restore.sh file. Internally the dump and restore procedures are based on
COPY TO and COPY FROM commands, so they are quite performant even for
large datasets. They could trivially be extended to perform binary
dump/restore, if needed.
"""

import os
import shutil
import zipfile
import argparse
from django.db import connection

README = '''\
To restore a hazard computation and all of its outputs into a new database,
follow this procedure.

1. go in the directory where this README is
2. run ``source restore.sh``

The restore may fail if your database already contains a hazard calculation
with the same id. If you think that the hazard calculation on your database
is not important and can removed together with all of its outputs, then
remove it by using ``bin/openquake --delete-hazard-calculation`` (which
must be run by an user with sufficient permissions). Then run again
``source restore.sh``.
'''

def tuplestr(row):
    return '(%s)' % ', '.join(str(x) for x in row)

class Cursor(object):
    """
    Small wrapper around a psycopg2 cursor
    """
    def __init__(self, psycopg2_cursor):
        self._cursor = psycopg2_cursor

    def tuplestr(self, query, *args):
        "Retrieve tuples of ids a strings"
        self._cursor.execute(query, args)
        return tuplestr(row[0] for row in self._cursor)

    def fetchall(self, query, *args):
        "Dispatch to .fetchall"
        self._cursor.execute(query, args)
        return self._cursor.fetchall()

    def copy(self, query, dest, name, mode):
        """
        Performs a COPY TO/FROM operation; sql is the query, dest
        is the destination directory, name is the destination name
        and mode is 'w' (for COPY TO) or 'r' (for COPY FROM).
        """
        fname = os.path.join(dest, name)
        print '%s (-> %s)' % (query, fname)
        with open(fname, mode) as f:
            self._cursor.copy_expert(query, f)

def zipdir(dirpath):
    "zip the contents of a directory in a zipfile and remove the directory"
    with zipfile.ZipFile(dirpath + '.zip', 'w') as z:
        for name in os.listdir(dirpath):
            z.write(os.path.join(dirpath, name))
    shutil.rmtree(dirpath)
    return dirpath + '.zip'

def restore_cmd(*names):
    'Return a list of COPY FROM commands'
    return ["COPY %s FROM 'PWD/%s.csv';\n" % (name, name.split('.')[-1])
            for name in names]

def dump_hazard_calculation(curs, id_, dest):
    curs.copy("""copy (select * from uiapi.hazard_calculation where id=%s)
              to stdout""" % id_, dest, 'hazard_calculation.csv', 'w')
    curs.copy("""copy (select * from hzrdr.lt_realization
              where hazard_calculation_id=%s)
              to stdout""" % id_, dest, 'lt_realization.csv', 'w')
    return restore_cmd('uiapi.hazard_calculation', 'hzrdr.lt_realization')

def dump_oq_job(curs, id_, dest):
    curs.copy("""copy (select * from uiapi.oq_job where id in %s)
              to stdout""" % id_, dest, 'oq_job.csv', 'w')
    return restore_cmd('uiapi.oq_job')

def dump_output(curs, ids, dest):
    curs.copy("""copy (select * from uiapi.output where id in %s)
              to stdout""" % ids, dest, 'output.csv', 'w')
    return restore_cmd('uiapi.output')

def dump_hazard_curve(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.hazard_curve where output_id in %s)
              to stdout""" % output, dest, 'hazard_curve.csv', 'w')

    ids = curs.tuplestr(
        'select id from hzrdr.hazard_curve where output_id in %s' % output)
    curs.copy("""copy (select * from hzrdr.hazard_curve_data
              where hazard_curve_id in {})
              to stdout""".format(ids), dest, 'hazard_curve_data.csv', 'w')

    return restore_cmd('hzrdr.hazard_curve', 'hzrdr.hazard_curve_data')

def dump_gmf_collection(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.gmf_collection
              where output_id in %s)
              to stdout""" % output, dest, 'gmf_collection.csv', 'w')

    coll_ids = curs.tuplestr('select id from hzrdr.gmf_collection '
                             'where output_id in %s' % output)
    curs.copy("""copy (select * from hzrdr.gmf_set
              where gmf_collection_id in %s)
              to stdout""" % coll_ids, dest, 'gmf_set.csv', 'w')

    set_ids = curs.tuplestr('select id from hzrdr.gmf_set '
                            'where gmf_collection_id in %s' % coll_ids)
    curs.copy("""copy (select * from hzrdr.gmf where gmf_set_id in {})
              to stdout""".format(set_ids), dest, 'gmf.csv', 'w')

    return restore_cmd('hzrdr.gmf_collection', 'hzrdr.gmf_set', 'hzrdr.gmf')

def dump_gmf_scenario(curs, output, dest):
    curs.copy("""copy (select * from hzrdr.gmf_scenario
                 where output_id in %s)
                 to stdout""" % output, dest, 'gmf_scenario.csv', 'w')
    return restore_cmd('hzrdr.gmf_scenario')

def main(hazard_calculation_id):
    """
    Dump a hazard_calculation and its relative outputs.
    """
    out_dir = 'hc%s' % hazard_calculation_id
    if os.path.exists(out_dir):
        shutil.rmtree(out_dir)
    os.mkdir(out_dir)

    curs = Cursor(connection.cursor().cursor.cursor)

    jobs = curs.tuplestr(
        'select id from uiapi.oq_job where hazard_calculation_id =%s',
        hazard_calculation_id)

    outputs = curs.fetchall("""\
    select output_type, array_agg(id) from uiapi.output
    where oq_job_id in %s group by output_type
    having output_type in ('gmf', 'hazard_curve', 'gmf_scenario')
       """ % jobs)
    if not outputs:
        raise SystemExit('No outputs for jobs %s' % jobs)
    restore = dump_hazard_calculation(curs, hazard_calculation_id, out_dir)
    restore.extend(dump_oq_job(curs, jobs, out_dir))
    all_outs = sum([output_ids for output_type, output_ids in outputs], [])
    restore.extend(dump_output(curs, tuplestr(all_outs), out_dir))
    for output_type, output_ids in outputs:
        ids = tuplestr(output_ids)
        if output_type == 'hazard_curve':
            restore.extend(dump_hazard_curve(curs, ids, out_dir))
        elif output_type == 'gmf':
            restore.extend(dump_gmf_collection(curs, ids, out_dir))
        elif output_type == 'gmf_scenario':
            restore.extend(dump_gmf_scenario(curs, ids, out_dir))

    restore_script = os.path.join(out_dir, 'restore.sql')
    with open(restore_script, 'w') as f:
        for cmd in restore:
            f.write(cmd)
    with open(os.path.join(out_dir, 'restore.sh'), 'w') as f:
        f.write('sed -ie "s@PWD@`pwd`@g" restore.sql\n')
        f.write('psql openquake -f restore.sql\n')
    with open(os.path.join(out_dir, 'README.txt'), 'w') as f:
        f.write(README)
    print 'Written %s' % zipdir(out_dir)

if __name__ == '__main__':
    p = argparse.ArgumentParser()
    p.add_argument('hazard_calculation_id')
    arg = p.parse_args()
    main(arg.hazard_calculation_id)
<|endoftext|>


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

import requests
import sys
from bs4 import BeautifulSoup
import re
import logging
logging.basicConfig( )

#Scrap URL to fetch data
########################
def flipkart_scrapper(url):
    print ""
    print "scrapping Flipkart URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'      # define encoding at response level itself
    html = response.content            #fetch the entire HTML of the URL

    soup = BeautifulSoup(html,'html.parser')
    found = False

    #Scrap from metadata tag for Description or description
    desc= soup.find(attrs={'name':'Description'})
    if desc == None:
        desc= soup.find(attrs={'name':'description'})
    try:
        #print desc['content']
        desc =  desc['content']
    except :
        print "Meta tag Description 'Content' not found"

    #retrieve Item
    item = soup.find('h1', attrs={'class': '_3eAQiD'})   #to find out only the tag we are interested in
    if item== None :
        try :
            item_txt = desc.split("Buy ")[1].split("Rs. " )[0]   #if not found, try scrapping using Title metadata name : description
            print "Debug 1 : Item found:",item_txt
            found = True
        except:
            item_txt = " "
            found = False
            print "Error 1 : Product not found"
    else :
        try :
            item_txt = item.get_text( )         #to retrieve the item name text
            item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
            print "Debug 2 : item_txt  found : ", item_txt
            found = True
        except :
            item_txt = item
            found = False
            print "Error 2 : Product not found"

    #retrieve price
    price = soup.find('div', attrs={'class': '_1vC4OE _37U4_g'})
    if price== None :
        try :
            price_txt = int(desc.split("Rs. ")[1].split(" ")[0] )                #if not found, try scrapping using Title metadata name : description
            print "Debug 1 : Price found :",str(price_txt)
            found = True
        except :
            price_txt = 0
            found = False
            print "Error 1 : Price not found"
            pass
    else :
        try :
            price_txt = price.get_text( )          #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt)
            print "Debug 2 : Price found :",str(price_txt)
            found = True
        except :
            price_txt = 0
            found = False
            print "Error 2 : Price not found"
            pass

    #print  "Present price  of  " + item_txt  + " on Flipkart is Rs. " + str(price_txt)
    print  "Present price  on Flipkart is Rs. " + str(price_txt)
    print ""
    return (price_txt, item_txt, found )

def amazon_scrapper(url):
    print ""
    print "scrapping Amazon URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'      # define encoding at response level itself
    html = response.content             #fetch the entire HTML of the URL

    soup = BeautifulSoup(html,'html.parser')
    found = False

    #retrieve Item
    item = soup.find('h1', attrs={'class': 'a-size-large a-spacing-none'})
    if item == None:
        try :
            item = soup.find('h1', attrs={'class': 'a-size-large a-spacing-none'})
            item_txt = item.get_text( ).encode(sys.stdout.encoding, errors='replace' )
            item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
            print "Debug 1 : item_txt found :", item_txt
            found = True
        except :
            item_txt = ""
            found = False
            print "Error 1 : Product not found"
    else :
        item_txt = item.get_text( )  #to retrieve the item name text
        item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
        print "Debug 2 : item_txt found :", item_txt
        found = True

    #retrieve price
    price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
    if price ==None:
        try :
            price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
            price_txt = price.get_text( ).encode(sys.stdout.encoding, errors='replace' )  #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt ) / 100
            found = True
            print "Debug 1 : Price found :",price_txt
        except :
            price_txt = 0
        found = False
        print "Error 1 : Price not found"
        pass
    else :
        try :
            price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
            price_txt = price.get_text( ) #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt ) / 100
            found = True
            print "Debug 2 : Price found :",price_txt
        except :
            price_txt = 0
            found = False
            print "Error 2 : Price not found"
            pass

    print  "Present price  of  "+item_txt + " on  Amazon  is Rs. " + str(price_txt)
    print ""
    return (price_txt, item_txt, found )

def snapdeal_scrapper(url):
    print ""
    print "scrapping Snapdeal URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'
    html = response.content            #fetch the entire HTML of the URL
    #print html
     #WorkAround : to solve issue  :"bs4.dammit:Some characters could not be decoded, and were replaced with REPLACEMENT CHARACTER."
    #html = html.decode('latin-1')
    #html = html.decode('utf-8', 'ignore')
    soup = BeautifulSoup(html,'html.parser')
    #print html
    found = False

    #retrieve Item
    try :
         #retrieve Item
         item = soup.find('h1', attrs={'class': 'pdp-e-i-head'})   #to find out only the tag we are interested in
         #print item
         #item_txt = item.get_text( ).encode(sys.stdout.encoding, errors='replace' )  #to retrieve the item name text
         item_txt = item.get_text( )
         item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
         #print item_txt
         found = True
    except:
        item_txt = ""
        found = False
        print "Product not found"

    #Retrieve price
    try :
        print "getting price"
        price = soup.find('span', attrs={'class': 'payBlkBig'})
        price_txt = price.get_text( )  #to retrieve the item name text
        #Removing Non Numeric symbols from Price
        price_txt = re.sub("[^0-9]", "",price_txt )
        print price_txt
        price_txt = int(price_txt )
        found = True
        print "Price found"
    except :
        price_txt = 0
        found = False
        pass

    print  "Present price  of  "+item_txt + " on  Snapdeal  is Rs. " + str(price_txt)
    print ""
    return (price_txt, item_txt, found )
<commit_msg>Issue : flipkart str concatenate issue<commit_after># -*- coding: utf-8 -*-

import requests
import sys
from bs4 import BeautifulSoup
import re
import logging
logging.basicConfig( )

#Scrap URL to fetch data
########################
def flipkart_scrapper(url):
    print ""
    print "scrapping Flipkart URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'      # define encoding at response level itself
    html = response.content            #fetch the entire HTML of the URL

    soup = BeautifulSoup(html,'html.parser')
    found = False

    #Scrap from metadata tag for Description or description
    desc= soup.find(attrs={'name':'Description'})
    if desc == None:
        desc= soup.find(attrs={'name':'description'})
    try:
        #print desc['content']
        desc =  desc['content']
    except :
        print "Meta tag Description 'Content' not found"

    #retrieve Item
    item = soup.find('h1', attrs={'class': '_3eAQiD'})   #to find out only the tag we are interested in
    if item== None :
        try :
            item_txt = desc.split("Buy ")[1].split("Rs. " )[0]   #if not found, try scrapping using Title metadata name : description
            print "Debug 1 : Item found:",item_txt
            found = True
        except:
            item_txt = " "
            found = False
            print "Error 1 : Product not found"
    else :
        try :
            item_txt = item.get_text( )         #to retrieve the item name text
            item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
            print "Debug 2 : item_txt  found : ", item_txt
            found = True
        except :
            item_txt = item
            found = False
            print "Error 2 : Product not found"

    #retrieve price
    price = soup.find('div', attrs={'class': '_1vC4OE _37U4_g'})
    if price== None :
        try :
            price_txt = int(desc.split("Rs. ")[1].split(" ")[0] )                #if not found, try scrapping using Title metadata name : description
            print "Debug 1 : Price found :",str(price_txt)
            found = True
        except :
            price_txt = 0
            found = False
            print "Error 1 : Price not found"
            pass
    else :
        try :
            price_txt = price.get_text( )          #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt)
            print "Debug 2 : Price found :",str(price_txt)
            found = True
        except :
            price_txt = 0
            found = False
            print "Error 2 : Price not found"
            pass

    print  "Present price  of  " + str(item_txt ) + " on Flipkart is Rs. " + str(price_txt)
    #print  "Present price  on Flipkart is Rs. ", price_txt
    print ""
    return (price_txt, item_txt, found )

def amazon_scrapper(url):
    print ""
    print "scrapping Amazon URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'      # define encoding at response level itself
    html = response.content             #fetch the entire HTML of the URL

    soup = BeautifulSoup(html,'html.parser')
    found = False

    #retrieve Item
    item = soup.find('h1', attrs={'class': 'a-size-large a-spacing-none'})
    if item == None:
        try :
            item = soup.find('h1', attrs={'class': 'a-size-large a-spacing-none'})
            item_txt = item.get_text( ).encode(sys.stdout.encoding, errors='replace' )
            item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
            print "Debug 1 : item_txt found :", item_txt
            found = True
        except :
            item_txt = ""
            found = False
            print "Error 1 : Product not found"
    else :
        item_txt = item.get_text( )  #to retrieve the item name text
        item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
        print "Debug 2 : item_txt found :", item_txt
        found = True

    #retrieve price
    price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
    if price ==None:
        try :
            price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
            price_txt = price.get_text( ).encode(sys.stdout.encoding, errors='replace' )  #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt ) / 100
            found = True
            print "Debug 1 : Price found :",price_txt
        except :
            price_txt = 0
        found = False
        print "Error 1 : Price not found"
        pass
    else :
        try :
            price = soup.find('span', attrs={'class': 'a-size-medium a-color-price'})
            price_txt = price.get_text( ) #to retrieve the item name text
            #Removing Non Numeric symbols from Price
            price_txt = re.sub("[^0-9]", "",price_txt )
            price_txt = int(price_txt ) / 100
            found = True
            print "Debug 2 : Price found :",price_txt
        except :
            price_txt = 0
            found = False
            print "Error 2 : Price not found"
            pass

    print  "Present price  of  "+item_txt + " on  Amazon  is Rs. " + str(price_txt)
    print ""
    return (price_txt, item_txt, found )

def snapdeal_scrapper(url):
    print ""
    print "scrapping Snapdeal URL"
    #include http header fields for Requests
    headers =   {
    'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding' : 'gzip, deflate, sdch, br',
    'Accept-Language' : 'en-US,en;q=0.8',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36'
    }
    #fetch response from Requests
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'
    html = response.content            #fetch the entire HTML of the URL
    #print html
     #WorkAround : to solve issue  :"bs4.dammit:Some characters could not be decoded, and were replaced with REPLACEMENT CHARACTER."
    #html = html.decode('latin-1')
    #html = html.decode('utf-8', 'ignore')
    soup = BeautifulSoup(html,'html.parser')
    #print html
    found = False

    #retrieve Item
    try :
         #retrieve Item
         item = soup.find('h1', attrs={'class': 'pdp-e-i-head'})   #to find out only the tag we are interested in
         #print item
         #item_txt = item.get_text( ).encode(sys.stdout.encoding, errors='replace' )  #to retrieve the item name text
         item_txt = item.get_text( )
         item_txt = item_txt.strip( )          # to remove trailing and leading whitespaces
         #print item_txt
         found = True
    except:
        item_txt = ""
        found = False
        print "Product not found"

    #Retrieve price
    try :
        print "getting price"
        price = soup.find('span', attrs={'class': 'payBlkBig'})
        price_txt = price.get_text( )  #to retrieve the item name text
        #Removing Non Numeric symbols from Price
        price_txt = re.sub("[^0-9]", "",price_txt )
        print price_txt
        price_txt = int(price_txt )
        found = True
        print "Price found"
    except :
        price_txt = 0
        found = False
        pass

    print  "Present price  of  "+item_txt + " on  Snapdeal  is Rs. " + str(price_txt)
    print ""
    return (price_txt, item_txt, found )
<|endoftext|>


<commit_before>"""Alignment with SNAP: http://snap.cs.berkeley.edu/
"""
import os

from bcbio import bam, utils
from bcbio.distributed.transaction import file_transaction
from bcbio.pipeline import config_utils
from bcbio.ngsalign import novoalign
from bcbio.provenance import do

def align(fastq_file, pair_file, index_dir, names, align_dir, data):
    """Perform piped alignment of fastq input files, generating sorted, deduplicated BAM.

    TODO: Use streaming with new development version of SNAP to feed into
    structural variation preparation de-duplication.
    """
    pair_file = pair_file if pair_file else ""
    out_file = os.path.join(align_dir, "{0}-sort.bam".format(names["lane"]))
    assert not data.get("align_split"), "Split alignments not supported with SNAP"
    snap = config_utils.get_program("snap", data["config"])
    num_cores = data["config"]["algorithm"].get("num_cores", 1)
    resources = config_utils.get_resources("snap", data["config"])
    sort_max_mem = int(config_utils.adjust_memory(resources.get("memory", "2g"),
                                                  num_cores, "increase", "g")[:-1]) - 64
    sort_mem_arg = "-sm %s" % sort_max_mem if sort_max_mem > 0 else ""
    rg_info = novoalign.get_rg_info(names)
    if not utils.file_exists(out_file):
        with file_transaction(out_file) as tx_out_file:
            with utils.curdir_tmpdir(data) as work_dir:
                if fastq_file.endswith(".bam"):
                    cmd_name = "paired" if bam.is_paired(fastq_file) else "single"
                else:
                    cmd_name = "single" if not pair_file else "paired"
                cmd = ("{snap} {cmd_name} {index_dir} {fastq_file} {pair_file} "
                       "-rg '{rg_info}' -t {num_cores} -so {sort_mem_arg} -o {tx_out_file}")
                do.run(cmd.format(**locals()), "SNAP alignment: %s" % names["sample"])
    data["work_bam"] = out_file
    return data

def align_bam(bam_file, index_dir, names, align_dir, data):
    return align(bam_file, None, index_dir, names, align_dir, data)

# Optional galaxy location file. Falls back on remap_index_fn if not found
galaxy_location_file = "snap_indices.loc"

def remap_index_fn(ref_file):
    """Map sequence references to snap reference directory, using standard layout.
    """
    snap_dir = os.path.join(os.path.dirname(ref_file), os.pardir, "snap")
    assert os.path.exists(snap_dir) and os.path.isdir(snap_dir), snap_dir
    return snap_dir
<commit_msg>SNAP aligner: use streaming de-duplication and sorting with samblaster and sambamba<commit_after>"""Alignment with SNAP: http://snap.cs.berkeley.edu/
"""
import os

from bcbio import bam, utils
from bcbio.distributed.transaction import file_transaction
from bcbio.pipeline import config_utils
from bcbio.ngsalign import novoalign, postalign
from bcbio.provenance import do

def align(fastq_file, pair_file, index_dir, names, align_dir, data):
    """Perform piped alignment of fastq input files, generating sorted, deduplicated BAM.

    TODO: Use streaming with new development version of SNAP to feed into
    structural variation preparation de-duplication.
    """
    pair_file = pair_file if pair_file else ""
    out_file = os.path.join(align_dir, "{0}-sort.bam".format(names["lane"]))
    assert not data.get("align_split"), "Split alignments not supported with SNAP"
    snap = config_utils.get_program("snap", data["config"])
    num_cores = data["config"]["algorithm"].get("num_cores", 1)
    resources = config_utils.get_resources("snap", data["config"])
    rg_info = novoalign.get_rg_info(names)
    is_paired = bam.is_paired(fastq_file) if fastq_file.endswith(".bam") else pair_file
    if not utils.file_exists(out_file):
        with postalign.tobam_cl(data, out_file, is_paired) as (tobam_cl, tx_out_file):
            cmd_name = "paired" if is_paired else "single"
            cmd = ("{snap} {cmd_name} {index_dir} {fastq_file} {pair_file} "
                   "-R '{rg_info}' -t {num_cores} -M -o -sam - | ")
            do.run(cmd.format(**locals()) + tobam_cl, "SNAP alignment: %s" % names["sample"])
    data["work_bam"] = out_file
    return data

def align_bam(bam_file, index_dir, names, align_dir, data):
    return align(bam_file, None, index_dir, names, align_dir, data)

# Optional galaxy location file. Falls back on remap_index_fn if not found
galaxy_location_file = "snap_indices.loc"

def remap_index_fn(ref_file):
    """Map sequence references to snap reference directory, using standard layout.
    """
    snap_dir = os.path.join(os.path.dirname(ref_file), os.pardir, "snap")
    assert os.path.exists(snap_dir) and os.path.isdir(snap_dir), snap_dir
    return snap_dir
<|endoftext|>


<commit_before>#!/usr/bin/env python

import sys, os, collections, sqlite3, sniper_lib, sniper_config, getopt

outputfilename = None
formatdefaultoutputfile = {'svg': 'topo.svg', 'text': 'topo.txt'}
validformats = ('svg', 'text')
format = 'svg'

def usage():
  print 'Usage: %s [-h|--help (help)]  [-o|--output (output filename/"-" for stdout)]  [-f|--format (options: %s)]' % (sys.argv[0], validformats)

try:
  opts, args = getopt.getopt(sys.argv[1:], "ho:f:", [ "help", "output=", "format=" ])
except getopt.GetoptError, e:
  print e
  usage()
  sys.exit()
for o, a in opts:
  if o == '-h' or o == '--help':
    usage()
    sys.exit()
  elif o == '-o' or o == '--output':
    outputfilename = a
  elif o == '-f' or o == '--format':
    if a not in validformats:
      print >> sys.stderr, '%s is not a valid format' % a
      usage()
      sys.exit()
    format = a
  else:
    usage()
    sys.exit()

if outputfilename == None:
  outputfilename = formatdefaultoutputfile[format]

if outputfilename == '-':
  output = sys.stdout
else:
  output = open(outputfilename, 'w')

names = ('hwcontext', 'smt', 'L1-I', 'L1-D', 'L2', 'L3', 'L4', 'dram-cache', 'dram-dir', 'dram-cntlr')
ids = dict([ (name, collections.defaultdict(lambda: None)) for name in names ])

max_id = 0
db = sqlite3.connect('sim.stats.sqlite3')
for name, lid, mid in db.execute('SELECT componentname, coreid, masterid FROM topology').fetchall():
  if name not in names:
    print >> sys.stderr, 'Unknown component', name
    continue
  ids[name][int(lid)] = int(mid)
  max_id = max(max_id, int(lid))

config = sniper_config.parse_config(open('sim.cfg').read())

def format_config(name, lid):
  caches = {'L1-I': 'l1_icache', 'L1-D': 'l1_icache', 'L2': 'l2_cache', 'L3': 'l3_cache', 'L4': 'l4_cache'}
  if name in caches:
    value = sniper_config.get_config(config, 'perf_model/%s/cache_size' % caches[name], lid)
    return sniper_lib.format_size(1024 * long(value), digits = 0)
  elif name == 'dram-cache':
    value = sniper_config.get_config(config, 'perf_model/dram/cache/cache_size', lid)
    return sniper_lib.format_size(1024 * long(value), digits = 0)
  else:
    return ''

if format == 'text':
  print >> output, ' '*20,
  for lid in range(max_id+1):
    print >> output, '%3d' % lid,
  print >> output

  for name in names:
    if ids[name].keys():
      print >> output, '%-20s' % name,
      for lid in range(max_id+1):
        mid = ids[name][lid]
        if mid is None:
          value = ' '
        elif mid == lid:
          value = 'X'
        else:
          value = '<'
        print >> output, '%3s' % value,
      print >> output

elif format == 'svg':
  margin_x = 50; step_x = 110
  margin_y = 50; step_y = 50
  items = []
  def paint_init(w, h):
    print >> output, '''\
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d">
<g style="stroke-width:.025in; fill:none">
''' % (2*margin_x + w * step_x, 2*margin_y + h * step_y)
  def paint_box((x, y), (w, h), label = 0, color = '#ffffff', zorder = 0):
    svg = '''\
<rect x="%d" y="%d" width="%d" height="%d" rx="0"
   style="stroke:#000000;stroke-width:1;stroke-linejoin:miter; stroke-linecap:butt;fill:%s;"/>
''' % (margin_x + x * step_x, margin_y + y * step_y, (w - .2) * step_x, (h - .2) * step_y, color)
    if label:
      svg += '''\
<text xml:space="preserve" x="%d" y="%d" fill="#000000"  font-family="Times" font-style="normal" font-weight="normal" font-size="12" text-anchor="start">%s</text>
''' % (margin_x + (x + .1) * step_x, margin_y + (y + .3) * step_y, label)
    items.append((zorder, svg))
  def paint_fini():
    for order, svg in sorted(items, reverse = True):
      print >> output, svg
    print >> output, '''\
</g>
</svg>
'''

  paint_init(max_id+3, len(names)+1)
  xpos = range(max_id+1)
  if ids['smt'].keys():
    x = -1
    for lid in range(max_id+1):
      if ids['smt'][lid] == lid:
        x += 1
      xpos[lid] = x
    ypos = [ 0 for _ in range(max_id+1) ]
    for lid in range(max_id+1):
      mid = ids['smt'][lid]
      paint_box((xpos[lid]+.05, ypos[mid]+.1), (1-.1, 1-.2), 'Core #%d' % lid)
      ypos[mid] += .7
    for lid in range(max_id+1):
      if ids['smt'][lid] == lid:
        paint_box((xpos[lid], 0), (1, ypos[mid] + .3), color = '#cccccc', zorder = 1)
    y = max(ypos) + .3
  else:
    for lid in range(max_id+1):
      paint_box((lid, 0), (1, 1), 'Core #%d' % lid)
    y = 1
  for name in names:
    if name in ('hwcontext', 'smt'): continue
    if ids[name]:
      size = 0
      for lid in range(max_id, -1, -1):
        if not ids['smt'] or ids['smt'][lid] == lid:
          size += 1
        if ids[name][lid] == lid:
          cfg = format_config(name, lid)
          if cfg:
            label = '%s (%s)' % (name, cfg)
          else:
            label = name
          paint_box((xpos[lid], y), (size, 1), label)
          if name == 'dram-cntlr':
            paint_box((xpos[lid]-.075, -.2), (size+.15, y+1+.4), color = '#dddddd', zorder = 2)
          size = 0
      y += 1
  paint_fini()
<commit_msg>[gen_topology] Allow module to be imported and called as a function<commit_after>#!/usr/bin/env python

import sys, os, collections, sqlite3, sniper_lib, sniper_config, getopt

def gen_topology(resultsdir = '.', jobid = None, outputobj = sys.stdout, format = 'svg', embedded = False):
  names = ('hwcontext', 'smt', 'L1-I', 'L1-D', 'L2', 'L3', 'L4', 'dram-cache', 'dram-dir', 'dram-cntlr')
  ids = dict([ (name, collections.defaultdict(lambda: None)) for name in names ])

  max_id = 0
  db = sqlite3.connect('sim.stats.sqlite3')
  for name, lid, mid in db.execute('SELECT componentname, coreid, masterid FROM topology').fetchall():
    if name not in names:
      print >> sys.stderr, 'Unknown component', name
      continue
    ids[name][int(lid)] = int(mid)
    max_id = max(max_id, int(lid))

  config = sniper_config.parse_config(open('sim.cfg').read())

  def format_config(name, lid):
    caches = {'L1-I': 'l1_icache', 'L1-D': 'l1_icache', 'L2': 'l2_cache', 'L3': 'l3_cache', 'L4': 'l4_cache'}
    if name in caches:
      value = sniper_config.get_config(config, 'perf_model/%s/cache_size' % caches[name], lid)
      return sniper_lib.format_size(1024 * long(value), digits = 0)
    elif name == 'dram-cache':
      value = sniper_config.get_config(config, 'perf_model/dram/cache/cache_size', lid)
      return sniper_lib.format_size(1024 * long(value), digits = 0)
    else:
      return ''

  if format == 'text':
    print >> outputobj, ' '*20,
    for lid in range(max_id+1):
      print >> outputobj, '%3d' % lid,
    print >> outputobj

    for name in names:
      if ids[name].keys():
        print >> outputobj, '%-20s' % name,
        for lid in range(max_id+1):
          mid = ids[name][lid]
          if mid is None:
            value = ' '
          elif mid == lid:
            value = 'X'
          else:
            value = '<'
          print >> outputobj, '%3s' % value,
        print >> outputobj

  elif format == 'svg':
    margin_x = 50; step_x = 110
    margin_y = 50; step_y = 50
    items = []
    def paint_init(w, h):
      if not embedded:
        print >> outputobj, '''\
  <?xml version="1.0" standalone="no"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
'''
      print >> outputobj, '''\
  <svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d">
  <g style="stroke-width:.025in; fill:none">
  ''' % (2*margin_x + w * step_x, 2*margin_y + h * step_y)
    def paint_box((x, y), (w, h), name = '', label = 0, color = '#ffffff', zorder = 0):
      svg = '''\
  <rect id="%s" x="%d" y="%d" width="%d" height="%d" rx="0"
     style="stroke:#000000;stroke-width:1;stroke-linejoin:miter; stroke-linecap:butt;fill:%s;"/>
  ''' % (name, margin_x + x * step_x, margin_y + y * step_y, (w - .2) * step_x, (h - .2) * step_y, color)
      if label:
        svg += '''\
  <text xml:space="preserve" x="%d" y="%d" fill="#000000"  font-family="Times" font-style="normal" font-weight="normal" font-size="12" text-anchor="start">%s</text>
  ''' % (margin_x + (x + .1) * step_x, margin_y + (y + .3) * step_y, label)
      items.append((zorder, svg))
    def paint_fini():
      for order, svg in sorted(items, reverse = True):
        print >> outputobj, svg
      print >> outputobj, '''\
  </g>
  </svg>
  '''

    paint_init(max_id+3, len(names)+1)
    xpos = range(max_id+1)
    if ids['smt'].keys():
      x = -1
      for lid in range(max_id+1):
        if ids['smt'][lid] == lid:
          x += 1
        xpos[lid] = x
      ypos = [ 0 for _ in range(max_id+1) ]
      for lid in range(max_id+1):
        mid = ids['smt'][lid]
        paint_box((xpos[lid]+.05, ypos[mid]+.1), (1-.1, 1-.2), 'core-%d' % lid, 'Core #%d' % lid)
        ypos[mid] += .7
      for lid in range(max_id+1):
        if ids['smt'][lid] == lid:
          paint_box((xpos[lid], 0), (1, ypos[mid] + .3), 'smt-%d' % lid, color = '#cccccc', zorder = 1)
      y = max(ypos) + .3
    else:
      for lid in range(max_id+1):
        paint_box((lid, 0), (1, 1), 'core-%d' % lid, 'Core #%d' % lid)
      y = 1
    for name in names:
      if name in ('hwcontext', 'smt'): continue
      if ids[name]:
        size = 0
        for lid in range(max_id, -1, -1):
          if not ids['smt'] or ids['smt'][lid] == lid:
            size += 1
          if ids[name][lid] == lid:
            cfg = format_config(name, lid)
            if cfg:
              label = '%s (%s)' % (name, cfg)
            else:
              label = name
            paint_box((xpos[lid], y), (size, 1), '%s-%d' % (name, lid), label)
            if name == 'dram-cntlr':
              paint_box((xpos[lid]-.075, -.2), (size+.15, y+1+.4), color = '#dddddd', zorder = 2)
            size = 0
        y += 1
    paint_fini()

if __name__ == '__main__':
  outputfilename = None
  formatdefaultoutputfile = {'svg': 'topo.svg', 'text': 'topo.txt'}
  validformats = ('svg', 'text')
  format = 'svg'

  def usage():
    print 'Usage: %s [-h|--help (help)]  [-o|--output (output filename/"-" for stdout)]  [-f|--format (options: %s)]' % (sys.argv[0], validformats)

  try:
    opts, args = getopt.getopt(sys.argv[1:], "ho:f:", [ "help", "output=", "format=" ])
  except getopt.GetoptError, e:
    print e
    usage()
    sys.exit()
  for o, a in opts:
    if o == '-h' or o == '--help':
      usage()
      sys.exit()
    elif o == '-o' or o == '--output':
      outputfilename = a
    elif o == '-f' or o == '--format':
      if a not in validformats:
        print >> sys.stderr, '%s is not a valid format' % a
        usage()
        sys.exit()
      format = a
    else:
      usage()
      sys.exit()

  if outputfilename == None:
    outputfilename = formatdefaultoutputfile[format]

  if outputfilename == '-':
    output = sys.stdout
  else:
    output = open(outputfilename, 'w')

  gen_topology(resultsdir = '.', outputobj = output, format = format)
<|endoftext|>


<commit_before><commit_msg>Redirect all-beta and all-aurora page.<commit_after><|endoftext|>


<commit_before>from ds18b20 import *
import argparse

def main():
    parser = argparse.ArgumentParser(description='Help Information for eems.',
                                     prog='eems',
                                     usage='eems <command> [options]')
    parser.add_argument('check',
                        help='Check sensor requirements.')
    parser.add_argument('read',
                        help='Read sensors once.')
    parser.add_argument('monitor',
                        help='Start monitoring sensors.')

    check_group = parser.add_argument_group('check_group', 'Options for check')
    check_group.add_argument('-m', '--modules',
                             help='Check required modules.')
    check_group.add_argument('-c', '--config',
                             help='Check config.txt file.')

    monitor_group = parser.add_argument_group('monitor_group',
                                              'Options for monitor')

    monitor_group.add_argument('--check',
                               help='Run check before monitoring.')
    monitor_group.add_argument('--csv',
                               help='Write values into csv file.')
    monitor_group.add_argument('--log',
                               help='Write log file.')
    monitor_group.add_argument('--noprint',
                               help='Disable console output.')
    monitor_group.add_argument('--interval',
                               help='Define measurement interval '
                                    '(default is 60s).',
                               type=int)
    monitor_group.add_argument('--duration',
                               help='Define maximum duration '
                                    '(default is infinity).',
                               type=int)

    args = parser.parse_args()

    if args.check:
        c = Check()
        if args.modules:
            c.w1_modules()
        elif args.config:
            c.w1_config()
        else:
            c.w1_config()
            c.w1_config()

    elif args.read:
        t = Temp()
        t.read_once()

    elif args.monitor:
        if args.check:
            check = True
        else:
            check = None
        if args.csv:
            csv = True
        else:
            csv = None
        if args.log:
            log = True
        else:
            log = None
        if args.noprint:
            console = False
        else:
            console = True
        if args.interval:
            interval = args.interval
        else:
            interval = None
        if args.duration:
            duration = args.interval
        else:
            duration = None
        t = Temp(check=check, csv=csv, log=log, console=console)
        t.start_read(interval=interval, duration=duration)
    else:
        parser.print_help()

if __name__ == "__main__":
    main()
<commit_msg>funktioniert aber nicht schön<commit_after>from ds18b20 import *
import argparse

def main():
    parser = argparse.ArgumentParser(prog='eems',
                                     usage='\n  eems <command> [options]')
    parser.add_argument('command',
                        help='Check sensor requirements.')
    # parser.add_argument('read',
    #                    help='Read sensors once.')
    # parser.add_argument('monitor',
    #                    help='Start monitoring sensors.')

    check_group = parser.add_argument_group('check_group', 'Options for check')
    check_group.add_argument('-m', '--modules', action='store_true',
                             help='Check required modules.')
    check_group.add_argument('-c', '--config', action='store_true',
                             help='Check config.txt file.')

    monitor_group = parser.add_argument_group('monitor_group',
                                              'Options for monitor')

    monitor_group.add_argument('--check', action='store_true',
                               help='Run check before monitoring.')
    monitor_group.add_argument('--csv', action='store_true',
                               help='Write values into csv file.')
    monitor_group.add_argument('--log', action='store_true',
                               help='Write log file.')
    monitor_group.add_argument('--noprint', action='store_true',
                               help='Disable console output.')
    monitor_group.add_argument('--interval',
                               help='Define measurement interval '
                                    '(default is 60s).',
                               type=int)
    monitor_group.add_argument('--duration',
                               help='Define maximum duration '
                                    '(default is infinity).',
                               type=int)

    args = parser.parse_args()
    # print args

    if args.command == 'check':
        c = Check()
        if args.modules is True:
            c.w1_modules()
        elif args.config is True:
            c.w1_config()
        else:
            c.w1_config()
            c.w1_config()

    elif args.command == 'read':
        t = Temp()
        t.read_once()

    elif args.command == 'monitor':
        if args.check is True:
            check = True
        else:
            check = None
        if args.csv is True:
            csv = True
        else:
            csv = None
        if args.log is True:
            log = True
        else:
            log = None
        if args.noprint is True:
            console = False
        else:
            console = True
        if args.interval:
            interval = args.interval
        else:
            interval = None
        if args.duration:
            duration = args.interval
        else:
            duration = None
        t = Temp(check=check, csv=csv, log=log, console=console)
        t.start_read(interval=interval, duration=duration)
    else:
        parser.print_help()

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


<commit_before>"""
Utility to read the xtf_ctypes file and generate an pyi file to facilitate type hinting.
Note: Not a general tool for this purpose, it only parses the __fields__ property
"""

import inspect
import ctypes
import os.path

XTF_CField = """
class CField:
    \"\"\"
    This is a redefinition of the _ctype.CField class, which is hidden in the ctypes API.
    This class is not intended to be used at runtime, but is here to allow for static typing of the XTF-classes.
    \"\"\"
    def __init__(self):
        self.offset = 0  # type: int
        self.size = 0  # type: int

"""

XTF_Base = """
class XTFBase(ctypes.LittleEndianStructure):
    \"\"\"
    Base class for all XTF ctypes.Structure children.
    Exposes basic utility like printing of fields and constructing class from a buffer.
    \"\"\"
    def __str__(self) -> str:
        pass

    def __new__(cls, buffer: IOBase = None):
        pass

    def __init__(self, buffer=None, *args, **kwargs):
        pass

"""

def ctype_struct_generator(module):
    module_structs = inspect.getmembers(module, predicate=(
        lambda x: (inspect.isclass(x) and ctypes.Structure in inspect.getmro(x))))

    # Sort by the line number in which the class appears
    module_structs.sort(key=lambda x: inspect.getsourcelines(x[1])[1])
    for name, obj in module_structs:
            if ctypes.Structure in inspect.getmro(obj) and hasattr(obj, '_fields_'):
                yield obj

def get_all_fields(obj):
    cur_obj = obj
    fields = []

    base_fields = []
    if obj.__bases__:
        for base in obj.__bases__:
            base_fields += get_all_fields(base)

    if hasattr(cur_obj, '_fields_'):
        return base_fields + getattr(cur_obj, '_fields_')
    else:
        return base_fields

def generate_pyi(module):
    # Retrieve classes that derive from ctypes.Structure
    c_structs = ctype_struct_generator(module)

    pyi_path = os.path.splitext(module.__file__)[0] + '.pyi'
    with open(pyi_path, 'w') as f:
        # Write imports
        f.writelines([
            'import ctypes\n',
            'import numpy as np\n',
            #'import {}\n'.format(module.__package__),
            'from io import IOBase, BytesIO\n'
            'from typing import List, Tuple, Dict, Callable, Any\n\n\n'
        ])

        # Write CField and XTFBase classes
        f.write(XTF_CField)
        f.write(XTF_Base)

        for struct in c_structs:
            base_names = [type.__name__ for type in struct.__bases__]
            f.write('class {}({}):\n'.format(struct.__name__, ','.join(base_names)))

            # Retrieve _fields_ for this class
            if hasattr(struct, '_fields_'):
                fields = struct._fields_
            else:
                fields = []

            # Write static fields (ctypes.CField)
            for name, type in fields:
                f.write(' ' * 4 + '{} = None  # type: CField\n'.format(name))

            if hasattr(struct, '_typing_static_'):
                for name, type in struct._typing_static_:
                    f.write(' ' * 4 + '{} = None  # type: {}\n'.format(name, type))

            # Write instance (typed) fields
            f.write('\n' + ' '*4 + 'def __init__(self):\n')
            for name, type in fields:
                # Handle arrays correctly by extracting the element type
                if ctypes.Array in type.__bases__:
                    if type._type_ in ctype_struct_generator(module):
                        # Array of structs defined elsewhere in the module
                        typename = 'ctypes.Array[{}]'.format(type._type_.__name__)
                    else:
                        # Array of types not defined in the module (ctype assumed)
                        typename = 'ctypes.Array[{}.{}]'.format(type._type_.__module__, type._type_.__name__)
                else:
                    typename = '{}.{}'.format(type.__module__, type.__name__)

                f.write(' '*8 + 'self.{} = None  # type: {}\n'.format(name, typename))

            if hasattr(struct, '_typing_instance_'):
                for name, type in struct._typing_instance_:
                    f.write(' ' * 8 + 'self.{} = None  # type: {}\n'.format(name, type))

            for name, fun in inspect.getmembers(struct, predicate=inspect.isfunction):
                if not (name.startswith('__') or name.endswith('__')):
                    f.write(' '*4 + 'def {}{}:\n'.format(name, inspect.signature(fun)) + ' '*8 + 'pass\n')

            f.write('\n\n')

if __name__ == '__main__':
    import pyxtf.xtf_ctypes
    generate_pyi(pyxtf.xtf_ctypes)

    import pyxtf.vendors.kongsberg
    generate_pyi(pyxtf.vendors.kongsberg)

<commit_msg>Skip __init__ generation if _fields_ is empty<commit_after>"""
Utility to read the xtf_ctypes file and generate an pyi file to facilitate type hinting.
Note: Not a general tool for this purpose, it only parses the __fields__ property
"""

import inspect
import ctypes
import os.path

XTF_CField = """
class CField:
    \"\"\"
    This is a redefinition of the _ctype.CField class, which is hidden in the ctypes API.
    This class is not intended to be used at runtime, but is here to allow for static typing of the XTF-classes.
    \"\"\"
    def __init__(self):
        self.offset = 0  # type: int
        self.size = 0  # type: int

"""

XTF_Base = """
class XTFBase(ctypes.LittleEndianStructure):
    \"\"\"
    Base class for all XTF ctypes.Structure children.
    Exposes basic utility like printing of fields and constructing class from a buffer.
    \"\"\"
    def __str__(self) -> str:
        pass

    def __new__(cls, buffer: IOBase = None):
        pass

    def __init__(self, buffer=None, *args, **kwargs):
        pass

"""

def ctype_struct_generator(module):
    module_structs = inspect.getmembers(module, predicate=(
        lambda x: (inspect.isclass(x) and ctypes.Structure in inspect.getmro(x))))

    # Sort by the line number in which the class appears
    module_structs.sort(key=lambda x: inspect.getsourcelines(x[1])[1])
    for name, obj in module_structs:
            if ctypes.Structure in inspect.getmro(obj) and hasattr(obj, '_fields_'):
                yield obj

def get_all_fields(obj):
    cur_obj = obj
    fields = []

    base_fields = []
    if obj.__bases__:
        for base in obj.__bases__:
            base_fields += get_all_fields(base)

    if hasattr(cur_obj, '_fields_'):
        return base_fields + getattr(cur_obj, '_fields_')
    else:
        return base_fields

def generate_pyi(module):
    # Retrieve classes that derive from ctypes.Structure
    c_structs = ctype_struct_generator(module)

    pyi_path = os.path.splitext(module.__file__)[0] + '.pyi'
    with open(pyi_path, 'w') as f:
        # Write imports
        f.writelines([
            'import ctypes\n',
            'import numpy as np\n',
            #'import {}\n'.format(module.__package__),
            'from io import IOBase, BytesIO\n'
            'from typing import List, Tuple, Dict, Callable, Any\n\n\n'
        ])

        # Write CField and XTFBase classes
        f.write(XTF_CField)
        f.write(XTF_Base)

        for struct in c_structs:
            base_names = [type.__name__ for type in struct.__bases__]
            f.write('class {}({}):\n'.format(struct.__name__, ','.join(base_names)))

            # Retrieve _fields_ for this class
            if hasattr(struct, '_fields_'):
                fields = struct._fields_
            else:
                fields = []

            # Write static fields (ctypes.CField)
            for name, type in fields:
                f.write(' ' * 4 + '{} = None  # type: CField\n'.format(name))

            if hasattr(struct, '_typing_static_'):
                for name, type in struct._typing_static_:
                    f.write(' ' * 4 + '{} = None  # type: {}\n'.format(name, type))

            # Write instance (typed) fields
            if fields:
                f.write('\n' + ' '*4 + 'def __init__(self):\n')
            for name, type in fields:
                # Handle arrays correctly by extracting the element type
                if ctypes.Array in type.__bases__:
                    if type._type_ in ctype_struct_generator(module):
                        # Array of structs defined elsewhere in the module
                        typename = 'ctypes.Array[{}]'.format(type._type_.__name__)
                    else:
                        # Array of types not defined in the module (ctype assumed)
                        typename = 'ctypes.Array[{}.{}]'.format(type._type_.__module__, type._type_.__name__)
                else:
                    typename = '{}.{}'.format(type.__module__, type.__name__)

                f.write(' '*8 + 'self.{} = None  # type: {}\n'.format(name, typename))

            if hasattr(struct, '_typing_instance_'):
                for name, type in struct._typing_instance_:
                    f.write(' ' * 8 + 'self.{} = None  # type: {}\n'.format(name, type))

            for name, fun in inspect.getmembers(struct, predicate=inspect.isfunction):
                if not (name.startswith('__') or name.endswith('__')):
                    f.write(' '*4 + 'def {}{}:\n'.format(name, inspect.signature(fun)) + ' '*8 + 'pass\n')

            f.write('\n\n')

if __name__ == '__main__':
    import pyxtf.xtf_ctypes
    generate_pyi(pyxtf.xtf_ctypes)

    import pyxtf.vendors.kongsberg
    generate_pyi(pyxtf.vendors.kongsberg)

<|endoftext|>


<commit_before>#  File       :	beer_song.py
#  Purpose    :	Write a program which produces the lyrics to that beloved
#               classic, that field-trip : 99 Bottles of Beer on the Wall.
#  Programmer : Amal Shehu
#  Course     :	Exercism
#  Date       :	Sunday 2 October 2016, 01:33 AM

def beer_song():
    for beer_count in range(99, 0, -1):
        if beer_count > 1:
            print beer_count, "bottles of beer on the wall,", beer_count, "bottles of beer."
            current_count = beer_count - 1
            print "Take one down, pass it around,", current_count, "bottles of beer on the wall."
            if beer_count > 2:
                suffix = str(beer_count - 1) + " bottles of beer on the wall."
            else:
                suffix = "1 bottle of beer on the wall."
        elif beer_count == 1:
            print "1 bottle of beer on the wall, 1 bottle of beer."
            suffix = "no more beer on the wall!"
            print "Take one down, pass it around,", suffix
            print "--"

beer_song()
<commit_msg>Reformat functions<commit_after>#  File       :	beer_song.py
#  Purpose    :	Write a program which produces the lyrics to that beloved
#               classic, that field-trip : 99 Bottles of Beer on the Wall.
#  Programmer : Amal Shehu
#  Course     :	Exercism
#  Date       :	Sunday 2 October 2016, 01:33 AM

def song():
    for beer_count in range(99, -1, -1):
        verse(beer_count)

def verse(beer_count):
    if beer_count > 1:
        print beer_count, "bottles of beer on the wall,", beer_count, "bottles of beer.\n"
        current_count = beer_count - 1
        print "Take one down and pass it around,", current_count, "bottles of beer on the wall.\n"
        if beer_count > 2:
            suffix = str(beer_count - 1) + " bottles of beer on the wall.\n"
        else:
            suffix = "1 bottle of beer on the wall.\n"
    elif beer_count == 1:
        print "1 bottle of beer on the wall, 1 bottle of beer.\n"
        suffix = "no more beer on the wall!\n"
        print "Take one down, pass it around,", suffix

    elif beer_count == 0:
        print "No more bottles of beer on the wall, no more bottles of beer.\n"
        print "Go to the store and buy some more, 99 bottles of beer on the wall.\n"
<|endoftext|>