# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import smart_selects.db_fields
import multiselectfield.db.fields
from django.conf import settings
import django.core.validators

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('lugar', '__first__'),
        ('organizacion', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Actividades_Produccion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Actividad de Producci\xf3n',
                'verbose_name_plural': 'Actividades de Producci\xf3n',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Adicional',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('interes', models.IntegerField(blank=True, null=True, verbose_name=b'Tiene interes en ampliar las \xc3\xa1reas de cacao', choices=[(1, b'Si'), (2, b'No')])),
                ('cuanto', models.FloatField(default=b'0', null=True, blank=True)),
            ],
            options={
                'verbose_name': 'Amplici\xf3n \xe1reas de cacao',
                'verbose_name_plural': 'Amplici\xf3n \xe1reas de cacao',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Area_Cacao',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('area', models.FloatField(verbose_name=b'\xc3\x81rea total de cacao establecida en finca(Mz)')),
            ],
            options={
                'verbose_name': '9 \xc1rea de cacao en finca',
                'verbose_name_plural': '9 \xc1rea de cacao en fincas',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Beneficios',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('beneficio', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Beneficio',
                'verbose_name_plural': 'Beneficios',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Capacitaciones_Socioeconomicas',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('capacitaciones_socio', models.IntegerField(verbose_name=b'Capacitaciones', choices=[(1, b'Formaci\xc3\xb3n y fortalecimiento organizacional'), (2, b'Contabilidad b\xc3\xa1sica y administraci\xc3\xb3n'), (3, b'Equidad de g\xc3\xa9nero'), (4, b'Manejo de cr\xc3\xa9ditos'), (5, b'Administraci\xc3\xb3n de peque\xc3\xb1os negocios'), (6, b'Gesti\xc3\xb3n empresarial'), (7, b'Cadena de valor de cacao'), (8, b'Transformaci\xc3\xb3n de cacao')])),
                ('opciones_socio', multiselectfield.db.fields.MultiSelectField(max_length=7, verbose_name=b'Opciones', choices=[(1, b'Jefe familia var\xc3\xb3n'), (2, b'Jefa familia mujer'), (3, b'Hijos'), (4, b'Hijas')])),
            ],
            options={
                'verbose_name': '13.2 Capacitaciones socioecon\xf3mico/org',
                'verbose_name_plural': '13.2 Capacitaciones socioecon\xf3mico/org',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Capacitaciones_Tecnicas',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('capacitaciones', models.IntegerField(choices=[(1, b'Regular en sombra'), (2, b'Poda'), (3, b'Manejo de plagas y enfermedades'), (4, b'Elaboraci\xc3\xb3n de abonos org\xc3\xa1nicos'), (5, b'Elaboraci\xc3\xb3n de productos para control de plagas'), (6, b'Establecimiento de vivero'), (7, b'Injertaci\xc3\xb3n de cacao'), (8, b'Selecci\xc3\xb3n de \xc3\xa1rboles \xc3\xa9lites para producci\xc3\xb3n de semillas'), (9, b'Manejo de post-cosecha (selecci\xc3\xb3n, cosecha, fermentado, secado)'), (10, b'Manejo de calidad de cacao'), (11, b'Certificaci\xc3\xb3n org\xc3\xa1nica')])),
                ('opciones', multiselectfield.db.fields.MultiSelectField(max_length=7, choices=[(1, b'Jefe familia var\xc3\xb3n'), (2, b'Jefa familia mujer'), (3, b'Hijos'), (4, b'Hijas')])),
            ],
            options={
                'verbose_name': '13.1 Capacitaci\xf3n familia',
                'verbose_name_plural': '13.1 Capacitaci\xf3n familia',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Caracterizacion_Terreno',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('textura_suelo', models.IntegerField(verbose_name=b'\xc2\xbfCu\xc3\xa1l es el tipo de textura del suelo?', choices=[(1, b'Arcilloso'), (2, b'Limoso'), (3, b'Arenoso'), (4, b'Franco'), (5, b'Franco arenoso')])),
                ('pendiente_terreno', models.IntegerField(verbose_name=b'\xc2\xbfCu\xc3\xa1l es la pendiente del terreno?', choices=[(1, b'Plana'), (2, b'Inclinada'), (3, b'Muy inclinada')])),
                ('contenido_hojarasca', models.IntegerField(verbose_name=b'\xc2\xbfC\xc3\xb3mo en el contenido de hojarasca?', choices=[(1, b'Alta'), (2, b'Medio'), (3, b'Baja')])),
                ('porfundidad_suelo', models.IntegerField(verbose_name=b'\xc2\xbfCu\xc3\xa1l es la profundidad de suelo?', choices=[(1, b'Poco profundo'), (2, b'Medio profundo'), (3, b'Muy profundo')])),
                ('drenaje_suelo', models.IntegerField(verbose_name=b'\xc2\xbfC\xc3\xb3mo en el drenaje del suelo?', choices=[(1, b'Bueno'), (2, b'Regular'), (3, b'Malo')])),
            ],
            options={
                'verbose_name': '5 Caracterizaci\xf3n de terreno',
                'verbose_name_plural': '5 Caracterizaci\xf3n de terreno',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Certificacion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('cacao_certificado', models.IntegerField(verbose_name=b'Posee \xc3\xa1reas de cacao certificada', choices=[(1, b'Si'), (2, b'No')])),
                ('mant_area_cacao', models.FloatField(null=True, verbose_name=b'Mantenimiento de \xc3\xa1rea de cacao (C$)', blank=True)),
                ('mant_area_finca', models.FloatField(null=True, verbose_name=b'Mantenimiento de la finca (C$)', blank=True)),
                ('costo_certificacion', models.FloatField(null=True, verbose_name=b'Costo de estar certificado', blank=True)),
            ],
            options={
                'verbose_name': '10-1 Tipo de certificaci\xf3n que posee',
                'verbose_name_plural': '10-1 Tipo de certificaci\xf3n que posee',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Comercializacion_Cacao',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('producto', models.IntegerField(choices=[(1, b'Mazorca de cacao (unidad)'), (2, b'Semilla para siembra (unidad)'), (3, b'Cacao en baba (qq)'), (4, b'Cacao rojo sin fermentar (qq)'), (5, b'Cacao fermentado (lb)'), (6, b'Chocolate artesanal (lb)'), (7, b'Cacao en polvo (lb)'), (8, b'Cacao procesado/ pinolillo (lb)'), (9, b'Cajeta de cacao (lb)'), (10, b'Pasta de cacao (lb)'), (11, b'Vino de cacao (lt)')])),
                ('auto_consumo', models.FloatField(verbose_name=b'Auto-consumo')),
                ('venta', models.FloatField()),
                ('precio_venta', models.FloatField(verbose_name=b'Precio venta por unidad')),
                ('quien_vende', multiselectfield.db.fields.MultiSelectField(max_length=7, verbose_name=b'\xc2\xbfA qui\xc3\xa9n le vende?', choices=[(1, b'Comunidad'), (2, b'Intermediario'), (3, b'Mercado'), (4, b'Cooperativa')])),
                ('donde_vende', models.ManyToManyField(to='lugar.Municipio', verbose_name=b'\xc2\xbfD\xc3\xb3nde lo vende?')),
            ],
            options={
                'verbose_name': '12 Comercializaci\xf3n de cacao',
                'verbose_name_plural': '12 Comercializaci\xf3n de cacao',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Distancia_Comercio_Cacao',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('distancia', models.FloatField()),
            ],
            options={
                'verbose_name': '12.1 Distancia recorrida (Km)',
                'verbose_name_plural': '12.1 Distancia recorrida (Km)',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Educacion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('rango', models.IntegerField(verbose_name=b'Selecci\xc3\xb3n', choices=[(1, b'Hombres mayores 31 a\xc3\xb1os'), (2, b'Mujeres mayores 31 a\xc3\xb1os'), (3, b'Hombre joven 19 a 30 a\xc3\xb1os'), (4, b'Mujer joven 19 a 30 a\xc3\xb1os'), (5, b'Hombre adoles. 13 a 18 a\xc3\xb1os'), (6, b'Mujer adoles. 13 a 18 a\xc3\xb1os'), (7, b'Ni\xc3\xb1os 0 a 12 a\xc3\xb1os'), (8, b'Ni\xc3\xb1as 0 a 12 a\xc3\xb1os'), (9, b'Ancianos (> 64 a\xc3\xb1os)')])),
                ('numero_total', models.IntegerField()),
                ('no_lee_ni_escribe', models.IntegerField()),
                ('primaria_incompleta', models.IntegerField()),
                ('primaria_completa', models.IntegerField()),
                ('secundaria_incompleta', models.IntegerField()),
                ('bachiller', models.IntegerField()),
                ('universitario_tecnico', models.IntegerField()),
                ('viven_fuera', models.IntegerField(verbose_name=b'N\xc3\xbamero de personas que viven fuera de la finca')),
            ],
            options={
                'verbose_name': '1-2 Nivel de educaci\xf3n de la Familia',
                'verbose_name_plural': '1-2 Nivel de educaci\xf3n de la Familia',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Encuesta',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('fecha', models.DateField()),
                ('anno', models.IntegerField()),
                ('organizacion', models.ForeignKey(verbose_name=b'Organizaci\xc3\xb3n', to='organizacion.Organizacion')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Familia',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('miembros', models.IntegerField(verbose_name=b'N\xc3\xbamero de miembros')),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '1-1 Miembros de la Familia',
                'verbose_name_plural': '1-1 Miembros de la Familia',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Fenomenos_Naturales',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('sequia', models.IntegerField(verbose_name=b'Sequ\xc3\xada', choices=[(1, b'Fuerte'), (2, b'Poco fuerte'), (3, b'Leve'), (4, b'No hubo')])),
                ('innundacion', models.IntegerField(verbose_name=b'Inundaci\xc3\xb3n', choices=[(1, b'Fuerte'), (2, b'Poco fuerte'), (3, b'Leve'), (4, b'No hubo')])),
                ('lluvia', models.IntegerField(choices=[(1, b'Fuerte'), (2, b'Poco fuerte'), (3, b'Leve'), (4, b'No hubo')])),
                ('viento', models.IntegerField(choices=[(1, b'Fuerte'), (2, b'Poco fuerte'), (3, b'Leve'), (4, b'No hubo')])),
                ('deslizamiento', models.IntegerField(choices=[(1, b'Fuerte'), (2, b'Poco fuerte'), (3, b'Leve'), (4, b'No hubo')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '6 Fen\xf3menos naturales',
                'verbose_name_plural': '6 Fen\xf3menos naturales',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Genero',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ingresos', models.IntegerField(verbose_name=b'\xc2\xbfUsted recibe ingresos por las actividades que realiza?', choices=[(1, b'Si'), (2, b'No')])),
                ('ingreso_mesual', models.FloatField(null=True, verbose_name=b'Ingreso mensual aproximado percibido', blank=True)),
                ('destino_ingresos', models.CharField(max_length=300, verbose_name=b'Destino de los ingresos percibidos')),
                ('decisiones', multiselectfield.db.fields.MultiSelectField(max_length=7, verbose_name=b'Decisiones sobre destino de la producci\xc3\xb3n', choices=[(1, b'Decide Usted sobre la siembra de cacao'), (2, b'Decide Usted sobre la cosecha de cacao'), (3, b'Decide Usted sobre la venta de cacao'), (4, b'Decide Usted sobre la Ingresos de cacao')])),
                ('actividades', models.ManyToManyField(to='monitoreo.Actividades_Produccion', verbose_name=b'Actividades en las que participa')),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '14 G\xe9nero',
                'verbose_name_plural': '14 G\xe9nero',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Genero_2',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ganaderia', models.IntegerField(verbose_name=b'Ganader\xc3\xada', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('granos_basicos', models.IntegerField(verbose_name=b'Granos B\xc3\xa1sicos', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('cacao', models.IntegerField(verbose_name=b'Cacao', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('cafe', models.IntegerField(verbose_name=b'Caf\xc3\xa9', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('madera', models.IntegerField(verbose_name=b'Madera', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': 'Sobre otros Ingresos',
                'verbose_name_plural': 'Sobre otros Ingresos',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Inversion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('invierte_cacao', models.IntegerField(verbose_name=b'Invierte en cacao', choices=[(1, b'Si'), (2, b'No')])),
                ('interes_invertrir', models.IntegerField(verbose_name=b'Inter\xc3\xa9s de invertir', choices=[(1, b'Si'), (2, b'No')])),
                ('falta_credito', models.IntegerField(verbose_name=b'Falta de cr\xc3\xa9dito', choices=[(1, b'Si'), (2, b'No')])),
                ('altos_intereses', models.IntegerField(choices=[(1, b'Si'), (2, b'No')])),
                ('robo_producto', models.IntegerField(verbose_name=b'Robo de producto', choices=[(1, b'Si'), (2, b'No')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '6 Inversi\xf3n',
                'verbose_name_plural': '6 Inversi\xf3n',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Lista_Certificaciones',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Certificaci\xf3n',
                'verbose_name_plural': 'Certificaciones',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Mitigacion_Riesgos',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('monitoreo_plagas', models.IntegerField(verbose_name=b'\xc2\xbfRealiza monitoreo de plagas y enfermedades?', choices=[(1, b'Si'), (2, b'No')])),
                ('manejo_cultivo', models.IntegerField(verbose_name=b'\xc2\xbfCuenta con un manejo adecuado para el cultivo?', choices=[(1, b'Si'), (2, b'No')])),
                ('manejo_recursos', models.IntegerField(verbose_name=b'\xc2\xbfDisponen suficiente recursos para manejo de finca?', choices=[(1, b'Si'), (2, b'No')])),
                ('almacenamiento_agua', models.IntegerField(verbose_name=b'\xc2\xbfCuenta con obras para almacenamiento de agua?', choices=[(1, b'Si'), (2, b'No')])),
                ('distribucion_cacao', models.IntegerField(verbose_name=b'\xc2\xbfParticipan en cadena de distribuci\xc3\xb3n de producto cacao?', choices=[(1, b'Si'), (2, b'No')])),
                ('venta_cacao', models.IntegerField(verbose_name=b'\xc2\xbfCuenta con un contrato para la venta de cacao?', choices=[(1, b'Si'), (2, b'No')])),
                ('tecnologia_secado', models.CharField(max_length=200, null=True, verbose_name=b'\xc2\xbfDispone de tecnolog\xc3\xada para el secado y almacenamiento de cosecha? Mencione', blank=True)),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '7 Mitigaci\xf3n de Riesgos',
                'verbose_name_plural': '7 Mitigaci\xf3n de Riesgos',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Organizacion_Asociada',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('socio', models.IntegerField(verbose_name=b'Trabaja con alguna Organizaci\xc3\xb3n/Instituci\xc3\xb3n', choices=[(1, b'Si'), (2, b'No')])),
                ('beneficios', models.ManyToManyField(to='monitoreo.Beneficios', null=True, verbose_name=b'Beneficios de estar asociado', blank=True)),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
                ('organizacion', models.ManyToManyField(to='organizacion.Organizacion', null=True, verbose_name=b'Organizaci\xc3\xb3n/Instituci\xc3\xb3n con la que trabaja', blank=True)),
            ],
            options={
                'verbose_name': '8 Org. productiva-comercial asociado',
                'verbose_name_plural': '8 Org. productiva-comercial asociado',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Paga_Certifica',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Qui\xe9n paga la certifica',
                'verbose_name_plural': 'Quienes pagan la certificaci\xf3n',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Persona',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200, verbose_name=b'Nombre de jefa/e de familia')),
                ('cedula', models.CharField(max_length=20, null=True, verbose_name=b'C\xc3\xa9ula de entrevistado/a', blank=True)),
                ('fecha_nacimiento', models.DateField(verbose_name=b'Fecha de nacimiento')),
                ('sexo', models.IntegerField(choices=[(1, b'Hombre'), (2, b'Mujer')])),
                ('latitud', models.FloatField(null=True, blank=True)),
                ('longitud', models.FloatField(null=True, blank=True)),
                ('comunidad', smart_selects.db_fields.ChainedForeignKey(chained_model_field=b'municipio', chained_field=b'municipio', auto_choose=True, to='lugar.Comunidad')),
                ('departamento', models.ForeignKey(to='lugar.Departamento')),
                ('municipio', smart_selects.db_fields.ChainedForeignKey(chained_model_field=b'departamento', chained_field=b'departamento', auto_choose=True, to='lugar.Municipio')),
            ],
            options={
                'verbose_name': 'Persona',
                'verbose_name_plural': 'Personas',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Plantacion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('edad', models.IntegerField(choices=[(1, b'Menor de un a\xc3\xb1o'), (2, b'De 1 a 3 a\xc3\xb1os'), (3, b'De 4 a 10 a\xc3\xb1os'), (4, b'De 10 a 20 a\xc3\xb1os'), (5, b'Mayores de 20 a\xc3\xb1os')])),
                ('area', models.FloatField(verbose_name=b'\xc3\x81rea en Mz')),
                ('edad_real', models.FloatField(verbose_name=b'Edad real de la Plantaci\xc3\xb3n (a\xc3\xb1os)')),
                ('numero_p_semilla', models.IntegerField(verbose_name=b'N\xc3\xbamero de plantas establecidas por semilla')),
                ('numero_p_injerto', models.IntegerField(verbose_name=b'N\xc3\xbamero de plantas establecidas por injerto')),
                ('numero_p_improductivas', models.IntegerField(verbose_name=b'N\xc3\xbamero de plantas improductivas en el \xc3\xa1rea')),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '9-1 Edad de la plantaci\xf3n',
                'verbose_name_plural': '9-1 Edad de la plantaci\xf3n',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Problemas_Cacao',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('fertilidad', models.IntegerField(verbose_name=b'Baja fertilidad del suelo', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('arboles', models.IntegerField(verbose_name=b'\xc3\x81rboles poco productivos', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('plantaciones', models.IntegerField(verbose_name=b'Plantaciones muy viejas', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('plagas', models.IntegerField(verbose_name=b'Plagas y enfermedades', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('produccion', models.IntegerField(verbose_name=b'Poca producci\xc3\xb3n', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('mano_obra', models.IntegerField(verbose_name=b'Poca disponibilidad de mano de obra', choices=[(1, b'1'), (2, b'2'), (3, b'3'), (4, b'4'), (5, b'5')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '13.3 Problemas \xe1rea de cacao',
                'verbose_name_plural': '13.3 Problemas \xe1rea de cacao',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Produccion_Cacao',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('produccion_c_baba', models.FloatField(verbose_name=b'Producci\xc3\xb3n cacao en baba (qq baba/seco)')),
                ('produccion_c_seco', models.FloatField(verbose_name=b'Producci\xc3\xb3n cacao seco sin fermentar (qq seco)')),
                ('produccion_c_fermentado', models.FloatField(verbose_name=b'Producci\xc3\xb3n cacao fermentado convencional (qq seco)')),
                ('produccion_c_organico', models.FloatField(verbose_name=b'Producci\xc3\xb3n cacao organico (qq seco)')),
                ('meses_produccion', multiselectfield.db.fields.MultiSelectField(max_length=26, verbose_name=b'Meses de mayor producci\xc3\xb3n de cacao', choices=[(1, b'Enero'), (2, b'Febrero'), (3, b'Marzo'), (4, b'Abril'), (5, b'Mayo'), (6, b'Junio'), (7, b'Julio'), (8, b'Agosto'), (9, b'Septiembre'), (10, b'Octubre'), (11, b'Noviembre'), (12, b'Diciembre')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '9-2 Producci\xf3n de cacao \xfaltimo a\xf1o',
                'verbose_name_plural': '9-2 Producci\xf3n de cacao \xfaltimo a\xf1o',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Profesion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Profesi\xf3n',
                'verbose_name_plural': 'Profesiones',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Quien_Certifica',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Qui\xe9n certifica',
                'verbose_name_plural': 'Quienes certifican',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Razones_Agricolas',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('plantas_improductivas', models.IntegerField(choices=[(1, b'Alto (40%)'), (2, b'Medio (30%)'), (3, b'Baja (10%)')])),
                ('plagas_enfermedades', models.IntegerField(verbose_name=b'Plagas y enfermedades', choices=[(1, b'Si'), (2, b'No')])),
                ('quemas', models.IntegerField(choices=[(1, b'Si'), (2, b'No')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '6 Razones agr\xedcolas',
                'verbose_name_plural': '6 Razones agr\xedcolas',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Razones_Mercado',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('bajo_precio', models.IntegerField(choices=[(1, b'Si'), (2, b'No')])),
                ('falta_venta', models.IntegerField(verbose_name=b'Falta de venta', choices=[(1, b'Si'), (2, b'No')])),
                ('estafa_contrato', models.IntegerField(verbose_name=b'Estafa de contrato', choices=[(1, b'Si'), (2, b'No')])),
                ('calidad_producto', models.IntegerField(verbose_name=b'Mala calidad de producto', choices=[(1, b'Si'), (2, b'No')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '6 Razones de mercado',
                'verbose_name_plural': '6 Razones de mercado',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Recolector',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Recolector',
                'verbose_name_plural': 'Recolectores',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Reforestacion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('enriquecimiento_bosques', models.IntegerField(verbose_name=b'Enriquecimiento de los bosques', choices=[(1, b'Si'), (2, b'No')])),
                ('proteccion_agua', models.IntegerField(verbose_name=b'Protecci\xc3\xb3n de fuentes de agua', choices=[(1, b'Si'), (2, b'No')])),
                ('cercas_vivas', models.IntegerField(verbose_name=b'Establecimiento de cercas viva', choices=[(1, b'Si'), (2, b'No')])),
                ('viveros', models.IntegerField(verbose_name=b'Establecimiento de viveros', choices=[(1, b'Si'), (2, b'No')])),
                ('siembre_cacao', models.IntegerField(verbose_name=b'Siembra de \xc3\xa1rboles en cacao', choices=[(1, b'Si'), (2, b'No')])),
                ('forestales', models.IntegerField(verbose_name=b'Plantaciones forestales', choices=[(1, b'Si'), (2, b'No')])),
                ('potrero', models.IntegerField(verbose_name=b'Siembra de \xc3\xa1rboles en potrero', choices=[(1, b'Si'), (2, b'No')])),
                ('frutales', models.IntegerField(verbose_name=b'Parcelas frutales', choices=[(1, b'Si'), (2, b'No')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '4 Reforestaci\xf3n',
                'verbose_name_plural': '4 Reforestaci\xf3n',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Situacion',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nombre', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Situaci\xf3n',
                'verbose_name_plural': 'Situaciones',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Tecnicas_Aplicadas',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('viveros', multiselectfield.db.fields.MultiSelectField(max_length=15, choices=[(1, b'Preparaci\xc3\xb3n del sitio'), (2, b'Preparaci\xc3\xb3n del sustrato'), (3, b'Llenado de bolsa'), (4, b'Selecci\xc3\xb3n de semilla'), (5, b'Siembra de semilla'), (6, b'Uso de riego'), (7, b'Control de malas hierba'), (8, b'Fertilizaci\xc3\xb3n org\xc3\xa1nica')])),
                ('fertilizacion', multiselectfield.db.fields.MultiSelectField(max_length=15, verbose_name=b'Pr\xc3\xa1cticas de fertilizaci\xc3\xb3n', choices=[(1, b'Aplicaci\xc3\xb3n de t\xc3\xa9 de esti\xc3\xa9rcol'), (2, b'Aplicaci\xc3\xb3n de gallinaza'), (3, b'Aplicaci\xc3\xb3n de Bocashi'), (4, b'Aplicaci\xc3\xb3n de foliares naturales'), (5, b'Uso de triple cal'), (6, b'Aplicaci\xc3\xb3n de lombrihumus'), (7, b'Aplicaci\xc3\xb3n de urea'), (8, b'Aplicaci\xc3\xb3n de fertilizante completo')])),
                ('pract_manejo_fis', multiselectfield.db.fields.MultiSelectField(max_length=11, verbose_name=b'Pr\xc3\xa1cticas de manejo fitosanitario', choices=[(1, b'Control de malas hierbas con machete'), (2, b'Aplica herbicidas para controlar las malas hierbas'), (3, b'Manejo de plagas con productos naturales'), (4, b'Manejo de enfermedades con productos naturales'), (5, b'Manejo de enfermedades con fungicidas'), (6, b'Recolecci\xc3\xb3n e eliminaci\xc3\xb3n de frutos enfermos')])),
                ('pract_manejo_prod', multiselectfield.db.fields.MultiSelectField(max_length=7, verbose_name=b'Pr\xc3\xa1cticas de manejo productivo', choices=[(1, b'Poda de formaci\xc3\xb3n'), (2, b'Poda de mantenimiento'), (3, b'Poda de rehabilitaci\xc3\xb3n o renovaci\xc3\xb3n'), (4, b'Regulaci\xc3\xb3n en sombra')])),
                ('pract_mejora_plat', multiselectfield.db.fields.MultiSelectField(max_length=7, verbose_name=b'Pr\xc3\xa1cticas de mejoramiento de la plantaci\xc3\xb3n', choices=[(1, b'Selecci\xc3\xb3n de \xc3\xa1rboles superiores'), (2, b'Injertaci\xc3\xb3n en \xc3\xa1rboles adultos'), (3, b'Renovaci\xc3\xb3n de \xc3\xa1rea con plantas injertadas'), (4, b'Enriquecimiento de \xc3\xa1reas con plantas injertadas')])),
                ('pract_manejo_post_c', multiselectfield.db.fields.MultiSelectField(max_length=15, verbose_name=b'Pr\xc3\xa1cticas de manejo postcosecha y beneficiado', choices=[(1, b'Selecci\xc3\xb3n y clasificaci\xc3\xb3n de mazorcas por variedad'), (2, b'Selecci\xc3\xb3n de cacao en baba a fermentar'), (3, b'Fermentaci\xc3\xb3n en sacos'), (4, b'Fermentaci\xc3\xb3n en cajones'), (5, b'Fermentaci\xc3\xb3n en cajillas'), (6, b'Lo vende en baba a un centro de acopio'), (7, b'Solo la saca de la mazorca y lo seca'), (8, b'Lo saca de la mazorca, lo lava y luego lo seca')])),
                ('acopio_cacao', models.IntegerField(verbose_name=b'Acopio de cacao en la comunidad/municipio', choices=[(1, b'Si'), (2, b'No')])),
                ('acopio_org', models.IntegerField(verbose_name=b'Asociaci\xc3\xb3n con Org. que acopia cacao', choices=[(1, b'Si'), (2, b'No')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '11 T\xe9cn. aplicadas \xe1rea de cacao',
                'verbose_name_plural': '11 T\xe9cn. aplicadas \xe1rea de cacao',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Tenencia_Propiedad',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('dueno_propiedad', models.IntegerField(verbose_name=b'Son ustedes due\xc3\xb1os de la propiedad', choices=[(1, b'Si'), (2, b'No')])),
                ('si', models.IntegerField(blank=True, null=True, verbose_name=b'En el caso Si, a nombre de quien esta la propiedad', choices=[(1, b'A nombre del Hombre'), (2, b'A nombre de la Mujer'), (3, b'A nombre de Hijas/hijos'), (4, b'A nombre del Hombre y Mujer'), (5, b'Colectivo')])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
                ('no', models.ForeignKey(verbose_name=b'En el caso que diga NO, especifique la situaci\xc3\xb3n', blank=True, to='monitoreo.Situacion', null=True)),
            ],
            options={
                'verbose_name': '2 Tenencia de Propiedad',
                'verbose_name_plural': '2 Tenencia de Propiedad',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Tipos_Servicio',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('servicio', models.CharField(max_length=200)),
            ],
            options={
                'verbose_name': 'Tipo de Servicio',
                'verbose_name_plural': 'Tipos de Servicios',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Uso_Tierra',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('area_total', models.FloatField(default=b'0', verbose_name=b'\xc3\x81rea total en manzanas de la propiedad', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(200)])),
                ('bosque', models.FloatField(default=b'0', verbose_name=b'Bosques', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('tacotal', models.FloatField(default=b'0', verbose_name=b'Tacotal o \xc3\xa1rea de descanso', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('cultivo_anual', models.FloatField(default=b'0', verbose_name=b'Cultivo anual ( que produce en el a\xc3\xb1o)', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('plantacion_forestal', models.FloatField(default=b'0', verbose_name=b'Plantaci\xc3\xb3n forestal ( madera y le\xc3\xb1a)', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('area_pasto_abierto', models.FloatField(default=b'0', verbose_name=b'\xc3\x81rea de pastos abierto', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('area_pasto_arboles', models.FloatField(default=b'0', verbose_name=b'\xc3\x81rea de pastos con \xc3\xa1rboles', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('cultivo_perenne', models.FloatField(default=b'0', verbose_name=b'Cultivo perenne (frutales)', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('cultivo_semi_perenne', models.FloatField(default=b'0', verbose_name=b'Cultivo semi-perenne (mus\xc3\xa1cea, pi\xc3\xb1a)', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('cacao', models.FloatField(default=b'0', verbose_name=b'Solo destinado para cacao', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('huerto_mixto_cacao', models.FloatField(default=b'0', verbose_name=b'Huerto mixto con cacao', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
                ('encuesta', models.ForeignKey(to='monitoreo.Encuesta')),
            ],
            options={
                'verbose_name': '3 Uso de Tierra',
                'verbose_name_plural': '3 Uso de Tierra',
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='persona',
            name='profesion',
            field=models.ForeignKey(to='monitoreo.Profesion'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='organizacion_asociada',
            name='tipos_servicio',
            field=models.ManyToManyField(to='monitoreo.Tipos_Servicio', null=True, verbose_name=b'Tipos de servicios que recibe', blank=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='encuesta',
            name='persona',
            field=models.ForeignKey(verbose_name=b'Nombre', to='monitoreo.Persona'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='encuesta',
            name='recolector',
            field=models.ForeignKey(to='monitoreo.Recolector'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='encuesta',
            name='usuario',
            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='educacion',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='distancia_comercio_cacao',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='comercializacion_cacao',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='certificacion',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='certificacion',
            name='paga_certificacion',
            field=models.ManyToManyField(to='monitoreo.Paga_Certifica', null=True, verbose_name=b'\xc2\xbfQui\xc3\xa9n paga la certificaci\xc3\xb3n?', blank=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='certificacion',
            name='quien_certifica',
            field=models.ManyToManyField(to='monitoreo.Quien_Certifica', null=True, verbose_name=b'\xc2\xbfQui\xc3\xa9n certifica?', blank=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='certificacion',
            name='tipo',
            field=models.ManyToManyField(to='monitoreo.Lista_Certificaciones', null=True, verbose_name=b'Tipo de certificaci\xc3\xb3n', blank=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='caracterizacion_terreno',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='capacitaciones_tecnicas',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='capacitaciones_socioeconomicas',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='area_cacao',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='adicional',
            name='encuesta',
            field=models.ForeignKey(to='monitoreo.Encuesta'),
            preserve_default=True,
        ),
    ]


# By Rose Kitz
# Comments with Anna Quiros
# FET Lab Summer 2022
# Written for Atlantis in PyVIEW

import struct
import ble_CBR
import bluetooth
import button
import time
import display
import math

import color_sensor as cs
import distance_sensor as ds
import port

time_between_note_loops = 10 # ms (see at end of Violin() loop)

# Initialize common inputs for note package
NoteOn = 0x90
NoteOff = 0x80
MaxVol = 127
MinVol = 0

# Left button ends program
done = lambda : button.button_isPressed(button.BUTTON_LEFT)[0]

# Initialize package to send BLE MIDI information
package = [0x00,0x00,0x00,0x00,0x00]

# Initialize sensors
string_color_sensor = port.PORTB
slide_distance_sensor = port.PORTD

# Create list of possible colors
lego_color_list = [LEGO_MAGENTA, LEGO_BLUE, LEGO_YELLOW, LEGO_RED]
lego_color_list_as_str = ['LEGO_MAGENTA', 'LEGO_BLUE', 'LEGO_YELLOW', 'LEGO_RED']

# --- LEGO color to violin string key ---
# Violin open string notes = [G3, D4, A4, E5]
# Leftmost color is the brick at END of bow = leftmost string if looking from hub to end of violin = G3 open string
# Second color is D4 open string
# Third color is A4 open string
# Rightmost color is brick nearest hand on bow = rightmost string looking from hub to end of violin = E5 open string

# Initialize buffer of error: no color over sensor
no_color_max = 5

# New 2D list to track min and max rgbi values for each color brick on the bow
# each inner list: [color_name, color_min_rgbi, color_max_rgbi]
all_colors_min_max_rgbi = []

# List to collect sets of rgbi values for initial calibration, to then calculate min/max values
all_colors_all_rgbi = []

# Minimum and maximum distances of violin finger board from the distance sensor
min_distance = 42 # [mm]
max_distance = 96 # [mm]

# Function to package up MIDI information to send over BLE
def note(cmd,value,volume):
    timestamp_ms = time.ticks_ms()
    package[0] = (timestamp_ms >> 7 & 0b111111) | 0x80
    package[1] =  0x80 | (timestamp_ms & 0b1111111)
    package[2] =  0x80 | cmd
    package[3] = value
    package[4] = volume
    return struct.pack("bbbbb", package[0], package[1], package[2], package[3], package[4])

# Calculates the current min and max rgbi values of the inputted rgbi list for current block
def calculate_rgbi_min_max(current_list_all_rgbi):

    # Initialize min and max value of each r, g, b, i as the first recorded values for each color
    # Assign min & max as first values to start
    min_rgbi = [current_list_all_rgbi[0][0], current_list_all_rgbi[0][1], current_list_all_rgbi[0][2], current_list_all_rgbi[0][3]]
    max_rgbi = [current_list_all_rgbi[0][0], current_list_all_rgbi[0][1], current_list_all_rgbi[0][2], current_list_all_rgbi[0][3]]
    current_num_training_colors = len(current_list_all_rgbi)

    # Loop through each test rgbi value set
    for i in range (current_num_training_colors):
        # Loop through each r, g, b, i of each set
        for j in range(4):

            current_value = current_list_all_rgbi[i][j]
            current_min = min_rgbi[j]
            current_max = max_rgbi[j]

            # Finds actual rgbi min / max
            if current_value < current_min:
                min_rgbi[j] = current_value
            if current_value > current_max:
                max_rgbi[j] = current_value

    return min_rgbi, max_rgbi

# Blinks middle row of pixels on hub light matrix
def blink_calibrating(start_or_stop):

    pixel_on = 100
    pixel_off = 0
    pixel_state = 0

    # At start, clear screen and turn pixels on in order
    if start_or_stop.lower() == 'start':
        display.display_clear()
        pixel_state = pixel_on
    # At end, turn pixels off in order
    else:
        pixel_state = pixel_off

    # Blink pixels in row 2 individually across screen
    # On or off depending on start or finish calibrating
    row = 2
    for i in range(5):
        display.display_set_pixel(i, row, pixel_state)
        time.sleep_ms(100)

# Program waits until user presses and releases right button to continue program
def wait_until_button_is_pressed_and_released():

    is_right_pressed = False # NOT pressed

    # Wait until user presses R button to indicate ready to calibrate color
    while not is_right_pressed:
        time.sleep_ms(1)

        right_pressed_or_not = button.button_isPressed(button.BUTTON_RIGHT)[0]

        if right_pressed_or_not == 1:
            is_right_pressed = True

    # Wait until button is released
    while is_right_pressed:
        time.sleep_ms(1)

        right_pressed_or_not = button.button_isPressed(button.BUTTON_RIGHT)[0]

        if right_pressed_or_not == 0:
            is_right_pressed = False

# Calibrates color sensor to find RGBI values associated with each LEGO color
def calibrate_color(block_color, string_index):

    # Initialize list of rgbi lists for training
    all_rgbi = []

    # Set number of times to test RGBI value
    num_tests = 100

    print("Hold the", block_color, "block CLOSE over the color sensor to calibrate and take", num_tests, "readings.")

    print("Press the right hub button when you are ready to start calibrating the", block_color, "block.")

    # Require right button to be both pressed and RELEASED to continue code
    wait_until_button_is_pressed_and_released()

    print("Starting to record values for the", block_color, "block.")

    # Start blinking lights to indicate calibrating
    blink_calibrating('start')

    current_min_rgbi = 0
    current_max_rgbi = 0

    # Get color sensor values
    for test in range(num_tests):

        # If in second half of tests, wait until user has bow far from sensor & right button pressed
        if test == 51:
            print("Hold the", block_color, "block FAR over the color sensor (near top of vertical magenta bar) to calibrate to take the second half of the readings.")
            print("Press the right hub button when you are ready to start calibrating the", block_color, "block.")

            wait_until_button_is_pressed_and_released()

        # Get current RGBI and convert from tuple to list
        current_rgbi = list(cs.get_rgbi(string_color_sensor))

        test_r = current_rgbi[0]
        test_g = current_rgbi[1]
        test_b = current_rgbi[2]
        test_i = current_rgbi[3]

        # Only count this sensed color as part of calibration if it's > [5, 5, 5, 5] (black)
        if (test_r > no_color_max) and (test_g > no_color_max) and (test_b > no_color_max) and (test_i > no_color_max):
            # If any r/g/b/i value is above 255, reset to 255 to avoid skewing max
            for value in range(4):
                if current_rgbi[value] > 255:
                    current_rgbi[value] = 255

            all_rgbi.append(current_rgbi)

    current_min_rgbi, current_max_rgbi = calculate_rgbi_min_max(all_rgbi)

    print("Press the right hub button to finish calibrating this color.")

    final_min_rgbi = 0
    final_max_rgbi = 0

    # Catch if no color data was collected / accepted
    if len(all_rgbi) == 0:
        print("No color data collected. Brick was likely held too far away from sensor.")
        print("Please re-calibrate this color brick.")

        final_min_rgbi, final_max_rgbi = calibrate_color(block_color, string_index)
    # Otherwise, continue code and return final values
    else:
        wait_until_button_is_pressed_and_released()

        final_min_rgbi = current_min_rgbi
        final_max_rgbi = current_max_rgbi

        global all_colors_all_rgbi
        # Append to all_colors_all_rgbi: first element = lego name/number of the color
        all_colors_all_rgbi.append([block_color])
        # Second element = list of calibrated rgbi values for this block so far
        all_colors_all_rgbi[string_index].append(all_rgbi)

    # Show lights for calibration ending
    blink_calibrating('stop')

    return final_min_rgbi, final_max_rgbi

# Guides user to calibrate multiple colors with the color sensor
def calibrate_all_colors():

    print("The program will prompt you through calibrating the colors on your bow to the color sensor.")
    print("Please make sure to move each brick up and down further and closer to the color sensor while calibrating.")

    num_strings = len(lego_color_list)

    global all_colors_min_max_rgbi

    # Calibrate all the strings (by their color)
    for current_string_num in range(num_strings):

        current_color_name = lego_color_list_as_str[current_string_num]

        color_min_rgbi, color_max_rgbi = calibrate_color(current_color_name, current_string_num)
        current_color_name_rgbi = [current_color_name, color_min_rgbi, color_max_rgbi]
        all_colors_min_max_rgbi.append(current_color_name_rgbi)

        print("Done calibrating", current_color_name, "color block.")

    print("Done calibrating all colors.")

# Gets current color (i.e. violin string), finds volume based on distance from the color sensor
def choose_string_and_volume():

    string_color = cs.get_color(string_color_sensor)

    # Initialize current_volume
    # If color not in list, returns min vol
    volume_from_color_distance = MinVol

    # Only train color min/max AND choose volume if color is in list
    if string_color in lego_color_list:
        # Get RGBI color
        string_color_rgbi = cs.get_rgbi(string_color_sensor)

        # Find index of current color in list
        string_color_index = lego_color_list.index(string_color)

        # Get [color_name, color_min_rgbi, color_max_rgbi] for current color brick
        current_color_and_min_max = all_colors_min_max_rgbi[string_color_index]

        # Combine new and old lists for color and re-find min / max
        current_min_max_and_new_rgbi = [current_color_and_min_max[1], current_color_and_min_max[2], string_color_rgbi]
        new_color_min_rgbi, new_color_max_rgbi = calculate_rgbi_min_max(current_min_max_and_new_rgbi)
        new_color_name_min_max = [string_color, new_color_min_rgbi, new_color_max_rgbi]
        all_colors_min_max_rgbi[string_color_index] = new_color_name_min_max

        # Find percentage the current color is between new min and max
        current_color_rgbi_percentage_btwn_min_max = []

        # Loop through R, G, B, I for this color brick to get percentage current RGBI is between min and max
        for i in range(len(new_color_min_rgbi)):

            # Only calculate percentage if range is not 0, or else will get divide by 0 error
            # If 0, leave value_percentage as 1 (play max volume)
            current_color_rgbi_range = new_color_max_rgbi[i] - new_color_min_rgbi[i]

            current_color_rgbi_diff = string_color_rgbi[i] - new_color_min_rgbi[i]

            value_percentage = 1
            if current_color_rgbi_range != 0:
                value_percentage = current_color_rgbi_diff / current_color_rgbi_range

            current_color_rgbi_percentage_btwn_min_max.append(value_percentage)

        # Min RGBI values = farthest distance away the color is detected
        # Max RGBI values = the closest distance away the color is detected

        # Get sum and average of r/g/b/i percentages between min and max
        sum_percentages = 0
        for percent in current_color_rgbi_percentage_btwn_min_max:
            sum_percentages += percent

        # Average percentage of min/max ≈ distance from color sensor
        # Higher =  closer
        # Lower = farther
        avg_percentage = sum_percentages / len(current_color_rgbi_percentage_btwn_min_max)

        vol_range = MaxVol - MinVol

        volume_from_color_distance = int(avg_percentage * vol_range) # Cast to int because volume can't be a decimal float

    return string_color, volume_from_color_distance

# Gets current distance of the finger board from sensor
def choose_distance():
    slide_distance = ds.get_distance(slide_distance_sensor)

    return slide_distance

# Gets frequency from distance and string, assuming values are not 0 or negative
def get_frequency_from_distance_and_string(string, distance):

    # Fundamental frequency equation: f1 = (1/2L)(T/M)^(1/2)
        # f1 = fundamental frequency
        # L = length of vibrating part of string = DISTANCE SENSED = distance
        # T = tension of string (depends on string chosen)
        # M = mass per unit length of string (depends on string chosen)

    frequency = 0 # [Hz]

    # LENGTH
    # Make proportional to real-world violin string
    standard_violin_string_length = 0.328 # [m]
    percentage_of_lego_distance = (distance - min_distance) / (max_distance - min_distance)
    real_life_string_distance = percentage_of_lego_distance * standard_violin_string_length # [m] length of vibrating string

    # TENSION and MASS PER UNIT LENGTH
    # Find T (tension) and M (mass per unit length) from string chosen
    # Source for typical T and M of violin strings: http://knutsacoustics.com/files/Typical-string-properties.pdf
    tension_and_mass_per_length_by_string_color = [[35.0, 0.00212], [34.3, 0.00092], [48.3, 0.00058], [71.4, 0.00038]]
    tension = 0
    mass_per_length = 0

    # Find which string we want to play
    for color_index in range(len(lego_color_list)):
        if string == lego_color_list[color_index]:
            # Based on color, get list of this string/color's tension and mass per unit length
            current_t_and_m_list = tension_and_mass_per_length_by_string_color[color_index]
            tension = current_t_and_m_list[0]
            mass_per_length = current_t_and_m_list[1]

    # Find current fundamental frequency
    frequency = (1 / (2 * real_life_string_distance)) * ((tension / mass_per_length)**.5)

    return frequency

# Gets MIDI number from a frequency (iff freq is NOT zero)
def get_midi_num_from_frequency(freq):

    # Equation: m  =  12*log2(f/440 Hz) + 69
        # m = midi number, f = frequency (Hz)
        # math.log(a,Base) gets the log of number a with Base

    num_to_log = freq / 440
    midi_num = (12 * (math.log(num_to_log, 2))) + 69

    return int(midi_num) # Cast in case number is a decimal b/c note() can't take a float

# ----- MAIN FUNCTION TO RUN ALL CODE -----
def Violin():
    ble = bluetooth.BLE()
    p = ble_CBR.BLESimplePeripheral(ble, 'MIDI', 'MySPIKE')

    def on_rx(v):
        print("RX", v)

    p.on_write(on_rx)

    was_connected = False

    is_start = True

    while not done():
        if p.is_connected():

            if is_start:
                # Calibrate colors to start, as you play it will improve min/max
                calibrate_all_colors()

                is_start = False

                print("Let's play!")

            current_string, current_volume = choose_string_and_volume()

            current_distance = choose_distance()

            # Play note iff color in the color list is detected AND distance is NOT zero or negative
            if (current_string in lego_color_list) and ((current_distance - min_distance) > 0.0):

                current_frequency = get_frequency_from_distance_and_string(current_string, current_distance)
                current_midi_note = get_midi_num_from_frequency(current_frequency)

                # Volume changes (current_volume) based on distance the color is from sensor
                p.send(note(NoteOn,current_midi_note,current_volume))
                time.sleep_ms(10)
                p.send(note(NoteOff,current_midi_note,MinVol))
                time.sleep_ms(10)

        else:
            if was_connected:
                break

        time.sleep_ms(time_between_note_loops)

Violin()


#!/usr/bin/python3

import numpy as np
import jnius_config
import sys
import math

EARTH_RADIUS = 6371000
#EARTH_RADIUS = 6378137.0

utrecht_x = 3899275.0
utrecht_y = 348997.0
utrecht_z = 5026376.0

jnius_config.set_classpath('terra121_classes')
from jnius import autoclass

A = 6378137.0
B = 6356752.3142

ModifiedAirocean = autoclass("io.github.terra121.projection.ModifiedAirocean")
ScaleProjection = autoclass("io.github.terra121.projection.ScaleProjection")
GeographicProjection = autoclass("io.github.terra121.projection.GeographicProjection")
Orientation = autoclass("io.github.terra121.projection.GeographicProjection$Orientation")

base_projection = GeographicProjection.orientProjection(ModifiedAirocean(), Orientation.none)
projection = ScaleProjection(base_projection, 7318261.522857145, -7318261.522857145)

if __name__ == "__main__":
#    print ('__main__')
    if len(sys.argv)==1:
#        print ('converting from pipe')
        COUNTER = 0
        fd=0
        fd_out = open("result.txt", "w")
        fd = 1
        for line in sys.stdin:
#            print('LINE: ' + line)
            lines = np.array([line], dtype=str)
            v = lines
            v = np.char.split(v, " ")
            v = np.array(list(v))[:, 0:2]
            for i in range(len(v)):
#                if v[i,0] == 'dummy':
#                    print('got dummy')
                if v[i,0] != 'ready' and v[i,0] != 'dummy':
                    if fd==0:
                        fd_out = open("result.txt", "w")
                        fd = 1
                    COUNTER=COUNTER + 1

                    REGIONX=float(v[i, 0].astype(float))
                    REGIONZ=float(v[i, 1].astype(float))
#                    print( 'IN: ' + str(REGIONX) + ' ' + str(REGIONZ) + ' (' + str(COUNTER) + ')' )
                    INT_REGIONX=int(REGIONX)
                    INT_REGIONZ=int(REGIONZ)
                    COORDS=projection.toGeo(*np.array([(REGIONX)*512, (REGIONZ)*512]))

#                    print(
#                        '{:17.13f}'.format(COORDS[0]) + ' ' + '{:17.13f}'.format(COORDS[1]) + ' '
#                        'r' + '.' + str(INT_REGIONX) + '.' + str(INT_REGIONZ) + ' ' +
#                        '[' + '{:.4f}'.format( (REGIONX) ) + ',' + '{:.4f}'.format( (REGIONZ) ) + ']'
#                    )
                    fd_out.write(
                        '{:17.13f}'.format(COORDS[0]) + ' ' + '{:17.13f}'.format(COORDS[1]) + ' ' +
                        'r' + '.' + str(INT_REGIONX) + '.' + str(INT_REGIONZ) + ' ' +
                        '[' + '{:.4f}'.format( (REGIONX) ) + ',' + '{:.4f}'.format( (REGIONZ) ) + ']' +
                        '\n'
                    )
                else:
#                    print('got ready')
                    fd_out.close()
                    fd_out = open("geo_ready.txt", "w")
                    fd_out.write( 'ready. ' + str(COUNTER) + ' converted' + '\n')
                    fd_out.close()
                    fd=0;

    if len(sys.argv)==3:
            REGIONX=float(sys.argv[1])
            REGIONZ=float(sys.argv[2])
            print( 'IN: ' + str(REGIONX) + ' ' + str(REGIONZ) )
            INT_REGIONX=int(REGIONX)
            INT_REGIONZ=int(REGIONZ)
            COORDS=projection.toGeo(*np.array([REGIONX*512, REGIONZ*512]))

            fd_out = open("result.txt", "w")
#            print(
#                '{:17.13f}'.format(COORDS[0]) + ' ' + '{:17.13f}'.format(COORDS[1]) + ' '
#                'r' + '.' + str(INT_REGIONX) + '.' + str(INT_REGIONZ) + ' ' +
#                '[' + '{:.4f}'.format( (REGIONX) ) + ',' + '{:.4f}'.format( (REGIONZ) ) + ']'
#            )
            fd_out.write(
                '{:17.13f}'.format(COORDS[0]) + ' ' + '{:17.13f}'.format(COORDS[1]) + ' ' +
                'r' + '.' + str(INT_REGIONX) + '.' + str(INT_REGIONZ) + ' ' +
                '[' + '{:.4f}'.format( (REGIONX) ) + ',' + '{:.4f}'.format( (REGIONZ) ) + ']' +
                '\n'
            )

            fd_out.close()
            fd_out = open("geo_ready.txt", "w")
            fd_out.write( 'ready.')
            fd_out.close()


import requests
import threading
import time
import sys

n= int(sys.argv[2])
port = sys.argv[1]
print(port)

def HEAD_REQUEST(url,n):
	print(n)
	try:
		r = requests.head(url)
		print(r.status_code)
		print(r.text)
		print(r.headers)
	except:
		print('Unsuccessful')
	return

if __name__=='__main__':
	list_threads=[]
	while(n):
		client_thread = threading.Thread(target = HEAD_REQUEST, args = ['http://127.0.0.1:'+port+'/myindex.html',n])
		client_thread.start()
		print('in main')
		list_threads.append(client_thread)
		n = n-1

	for threads in list_threads:
		threads.join()


from mip import Model, BINARY, xsum, OptimizationStatus

# terminal colors
black = lambda text: '\033[0;30m' + text + '\033[0m'
red = lambda text: '\033[0;31m' + text + '\033[0m'
green = lambda text: '\033[0;32m' + text + '\033[0m'
yellow = lambda text: '\033[0;33m' + text + '\033[0m'
blue = lambda text: '\033[0;34m' + text + '\033[0m'
magenta = lambda text: '\033[0;35m' + text + '\033[0m'
cyan = lambda text: '\033[0;36m' + text + '\033[0m'
white = lambda text: '\033[0;37m' + text + '\033[0m'

# actual problem
model = Model('thinkmathone')
model.verbose = 0
n = 7
x = []
for i in range(0, n):
    x.append([])
    for j in range(0, n):
        x[i].append(model.add_var(var_type=BINARY, name=f'x_${i}_${j}'))

b = []
for i in range(0, n):
    b.append([])
    for j in range(0, n):
        b[i].append(model.add_var(var_type=BINARY, name=f'b_${i}_${j}'))

for i in range(0, n):
    for j in range(0, n):
        b[i][j] = 1 - x[(j - i) % n][j]

# x can only be one of 0..n
for i in range(0, n):
    model += 1 == xsum(x[i][j] for j in range(n))

# each x is different
for i in range(0, n):
    expr = 0 + x[0][i]
    for j in range(1, n):
        expr += x[j][i]
    model += 1 == expr

# only one can be satisfied
for i in range(0, n):
    model += xsum(b[i][j] for j in range(n)) == n - 1

# symmetry breaking constraint
model += x[0][0] == 1
cntSolutions = 0
while True:
    result = model.optimize()
    if result != OptimizationStatus.OPTIMAL:
        # no more solutions are found
        break

    cntSolutions += 1
    print('Seating:')
    y = []
    for i in range(0, n):
        for j in range(0, n):
            if x[i][j].xi(0) >= 0.9:
                print(f'x[{i}][{j}]')
                y.append(j)

    # print out all permutations
    print('Permutations:')
    for i in range(0, n):
        print(f'permutation {i}:')
        for j in range(0, n):
            print(j, end='')
        print()
        for j in range(0, n):
            val = y[(j + i) % n]
            if j == val:
                print(red(str(val)), end='')
            else:
                print(val, end='')
        print()

    print()
    print()
    # exclude current solution
    tmp = 0 + x[0][y[0]]
    for i in range(1, n):
        tmp += x[i][y[i]]
    model += tmp <= n - 1

print(f'Total solutions: {cntSolutions}')


# %%
# imports
from console.spcm_control.ddc import apply_ddc
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.optimize import curve_fit

# %%

raw = np.loadtxt("/home/schote01/data/reference_signal/data_1.txt")

f_spcm = 20e6
f_0 = 2.031e6
kernel_size = 400

filtered = apply_ddc(raw, kernel_size=kernel_size, f_0=f_0, f_spcm=f_spcm)[:-2]

dwell_time = kernel_size / 2 / f_spcm
t_filered = np.arange(filtered.size) * dwell_time

# >> Option 1: Using 1D filter
# b, a = signal.butter(1, 0.3)
# phase_fit = signal.filtfilt(b, a, np.angle(filtered))

# >> Option 2: Polyfit (linear fit)
m_phi, b_phi = np.polyfit(t_filered, np.angle(filtered), 1)
phase_fit = m_phi * t_filered + b_phi
m_amp, b_amp = np.polyfit(t_filered, np.abs(filtered), 1)
amp_fit = m_amp * t_filered + b_amp

fig, ax = plt.subplots(1, 3, figsize=(18, 4))
n_samples_raw = 100
ax[0].plot(1e6 * np.arange(n_samples_raw)/f_spcm, raw[:n_samples_raw])
ax[0].set_ylabel("Raw Signal Amplitude [mV]")
ax[0].set_xlabel("t [us]")

ax[1].plot(1e3 * t_filered, np.abs(filtered), label="Filtered")
ax[1].plot(1e3 * t_filered, amp_fit, label="Linear fit")
ax[1].set_ylabel("Amplitude [mV]")
ax[1].set_ylim([1500, 2500])
ax[1].legend()

ax[2].plot(1e3 * t_filered, np.degrees(np.angle(filtered)), label="Filtered")
ax[2].plot(1e3 * t_filered, np.degrees(phase_fit), label="Linear fit")
ax[2].set_ylabel("Phase [°]")

_ = [a.set_xlabel("t [ms]") for a in ax[1:]]

# %%
# Check amplitudes
y_0 = np.max(raw)
duty_cycle = 0.5
y_eff = np.sqrt(duty_cycle * y_0**2)
y_filt_mean = np.mean(np.abs(filtered))

print(f"Effective amplitude of raw signal: {y_eff} mV")
print(f"Mean amplitude of filtered signal: {y_filt_mean} mV")
# %%


import numpy as np
import tensorflow as tf
from lib import utils
from lib import model_helper
from lib import vocab_utils
from KEFU3 import iterator_utils2
from tensorflow.python.ops import lookup_ops
# #UNK
# #N
# #PE
# #NH
# #NT
UNK_ENTITY = '#UNK'
NONE_ENTITY = '#N'
PAD_ENTITY = '#PE'
NOT_HEAD_ENTITY = '#NH'
NOT_TAIL_ENTITY = '#NT'

#NF
#PR
#NR
NONE_RELATION = '#NF'
PAD_RELATION = '#PR'
NOT_TBD = '#NR'

def load_knolwedge_graph(hparams):
    """
    加载和知识图谱相关的概念
    :param hparams:
    :return:
    """
    entity_dict_path = hparams['entity_path']
    relation_dict_path = hparams['relation_path']
    utils.print_out("load entity dict from %s" % entity_dict_path)
    utils.print_out("load relation dict from %s" % relation_dict_path)

    entity_embed_path = hparams['entity_embedding_path']
    relation_embed_path = hparams['relation_embedding_path']

    embed_dim = hparams['entity_dim']

    entity_vocab = lookup_ops.index_table_from_file(entity_dict_path, default_value=0)
    reverse_entity_vocab = lookup_ops.index_to_string_table_from_file(entity_dict_path, default_value=UNK_ENTITY)
    padding_entity_list = [UNK_ENTITY, NONE_ENTITY, PAD_ENTITY, NOT_HEAD_ENTITY, NOT_TAIL_ENTITY]
    padding_relation_list = [NONE_RELATION, PAD_RELATION, NOT_TBD]

    entity_list = []
    relation_list = []

    entity_dict = dict()
    relation_dict = dict()

    #  保证位置正确
    with open(entity_dict_path, encoding='utf-8') as f:
        for i, line in enumerate(f):
            e = line.strip()
            entity_list.append(e)
            entity_dict[e] = i
    for i in range(len(padding_entity_list)):
        assert padding_entity_list[i] == entity_list[i]

    with open(relation_dict_path, encoding='utf-8') as f:
        for i, line in enumerate(f):
            e = line.strip()
            relation_list.append(e)
            relation_dict[e] = i
    for i in range(len(padding_relation_list)):
        assert padding_relation_list[i] == relation_list[i]

    print("Loading entity vectors...")
    entity_embed = []
    with open(entity_embed_path, 'r+', encoding='utf-8') as f:
        for i, line in enumerate(f):
            if '\t' not in line:
                s = line.strip().split(' ')
            else:
                s = line.strip().split('\t')
            entity_embed.append([float(x) for x in s])

    print("Loading relation vectors...")
    relation_embed = []
    with open(relation_embed_path, 'r+', encoding='utf-8') as f:
        for i, line in enumerate(f):
            if '\t' not in line:
                s = line.strip().split(' ')
            else:
                s = line.strip().split('\t')
            relation_embed.append([float(x) for x in s])

    entity_embed = np.array(entity_embed, dtype=np.float32)
    relation_embed = np.array(relation_embed, dtype=np.float32)
    entity_embed = tf.get_variable('entity_embed', dtype=tf.float32, initializer=entity_embed, trainable=False)
    relation_embed = tf.get_variable('relation_embed', dtype=tf.float32, initializer=relation_embed, trainable=False)
    entity_embed = tf.reshape(entity_embed, [-1, embed_dim])
    relation_embed = tf.reshape(relation_embed, [-1, embed_dim])

    padding_entity_embedding = tf.get_variable('entity_padding_embed', [len(padding_entity_list), embed_dim], dtype=tf.float32,
                                     initializer=tf.zeros_initializer())
    padding_relation_embedding = tf.get_variable('relation_padding_embed', [len(padding_relation_list), embed_dim], dtype=tf.float32,
                                     initializer=tf.zeros_initializer())

    tf_entity_embed = tf.concat([padding_entity_embedding, entity_embed], axis=0)
    tf_relation_embed = tf.concat([padding_relation_embedding, relation_embed], axis=0)
    tf_entity_embed = tf.layers.dense(tf_entity_embed, hparams['entity_dim'], use_bias=False, name='entity_embedding')
    tf_relation_embed = tf.layers.dense(tf_relation_embed, hparams['entity_dim'], use_bias=False,  name='relation_embedding')
    tf_entity_embed = tf.concat([tf_entity_embed, tf_relation_embed], axis=0)

    # Facts
    utils.print_out('Loading facts')
    fact_dict_path = hparams['fact_path']
    entity_fact = []
    entity_target = []
    with open(fact_dict_path, encoding='utf-8') as fin:
        lines = fin.readlines()
        utils.print_out('Total Entity-Fact : %d' % len(lines))
        for line in lines:
            items = line.strip('\n').split()
            for i in [0, 1, 3]:
                items[i] = int(entity_dict.get(items[i], 0))
            items[2] = int(relation_dict.get(items[2])) + len(entity_dict) # realtion和 entity共用一个列表
            entity_fact.append(items[1:])
            entity_target.append(items[0])# uni ids
    entity_fact = np.array(entity_fact, dtype=np.int32)
    entity_target = np.array(entity_target, dtype=np.int32)
    entity_fact = np.reshape(entity_fact, [len(lines), 3])
    entity_target = np.reshape(entity_target, [len(lines)])
    tf_entity_fact = tf.constant(value=entity_fact, dtype=np.int32)
    tf_entity_target = tf.constant(value=entity_target, dtype=np.int32)

    tf_entity_fact_embedding = tf.nn.embedding_lookup(tf_entity_embed, tf_entity_fact)
    tf_entity_fact_embedding = tf.reshape(tf_entity_fact_embedding, [-1, 3*hparams['entity_dim']])

    return tf_entity_embed,tf_entity_fact_embedding, tf_entity_target, entity_vocab, reverse_entity_vocab

def create_gends_iterator_from_file(hparams, entity_vocab_table, is_eval=False):

    src_vocab_table, tgt_vocab_table = model_helper.create_vocab_from_file(hparams['src_vocab'], hparams['tgt_vocab'], hparams['share_vocab'])
    entity_vocab_table, _ = model_helper.create_vocab_from_file(hparams['entity_path'], hparams['entity_path'], True)
    union_vocab_table, _ = model_helper.create_vocab_from_file(hparams['uni_vocab'], hparams['uni_vocab'], True)
    # relative_vocab = src_vpcab_table + ENT0_ENT5
    relative_vocab_table, _ = model_helper.create_vocab_from_file(hparams['relative_vocab'], hparams['relative_vocab'], True)
    reverse_tgt_vocab_table = lookup_ops.index_to_string_table_from_file(
        hparams['relative_vocab'], default_value=vocab_utils.UNK)
    reverse_uni_vocab_table = lookup_ops.index_to_string_table_from_file(
        hparams['uni_vocab'], default_value=vocab_utils.UNK)

    src_file_placeholder = tf.placeholder(dtype=tf.string, shape=[], name='src_placeholder')
    entity_file_placeholder = tf.placeholder(dtype=tf.string, shape=[], name='src_entity_placeholder')
    tgt_in_file_placeholder = tf.placeholder(dtype=tf.string, shape=[], name='tgt_in_placeholder')
    tgt_out_file_placeholder = tf.placeholder(dtype=tf.string, shape=[], name='tgt_out_placeholder')
    fact_file_placeholder = tf.placeholder(dtype=tf.string, shape=[], name='fact_placeholder')
    src_dataset = tf.data.TextLineDataset(src_file_placeholder)
    ent_dataset = tf.data.TextLineDataset(entity_file_placeholder)
    tgt_in_dataset = tf.data.TextLineDataset(tgt_in_file_placeholder)
    tgt_out_dataset = tf.data.TextLineDataset(tgt_out_file_placeholder)
    fact_dataset = tf.data.TextLineDataset(fact_file_placeholder)
    skip_count_placeholder = tf.placeholder(shape=(), dtype=tf.int64)
    num_buckets = hparams['num_buckets'] if not is_eval else 1
    iterator = iterator_utils.get_iterator(
        src_dataset,
        ent_dataset,
        tgt_in_dataset,
        tgt_out_dataset,
        fact_dataset,
        src_vocab_table,
        entity_vocab_table,
        union_vocab_table,
        relative_vocab_table,
        random_seed=hparams['random_seed'],
        num_buckets=num_buckets,
        batch_size=hparams['batch_size'],
        sos=vocab_utils.SOS,
        eos=vocab_utils.EOS,
        src_max_len=hparams['src_max_len'],
        tgt_max_len=hparams['tgt_max_len'],
        shuffle=not is_eval,
        skip_count=skip_count_placeholder)

    return iterator, skip_count_placeholder, src_file_placeholder, entity_file_placeholder, tgt_in_file_placeholder,tgt_out_file_placeholder,fact_file_placeholder, src_vocab_table, tgt_vocab_table, reverse_tgt_vocab_table,reverse_uni_vocab_table


from persistent.list import PersistentList
from Products.MailHost.MailHost import _mungeHeaders
from Products.MailHost.MailHost import MailBase

class MockMailHost(MailBase):
    """A MailHost that collects messages instead of sending them."""

    def __init__(self, id):
        self.reset()

    def reset(self):
        self.messages = PersistentList()

    def _send(self, mfrom, mto, messageText, immediate=False):
        """Send the message"""
        self.messages.append(messageText)

    def send(
        self,
        messageText,
        mto=None,
        mfrom=None,
        subject=None,
        encode=None,
        immediate=False,
        charset=None,
        msg_type=None,
    ):
        messageText, mto, mfrom = _mungeHeaders(
            messageText, mto, mfrom, subject, charset=charset, msg_type=msg_type
        )
        self.messages.append(messageText)


"""This module allows sleeping excess time when updates aren't taking very
long"""
import time
import typing

class Ticker:
    """A callable object that sleeps excess time between invocations

    Attributes:
        target_secs (float): the target time between calls
        last_at (float, optional): result from time.time() at end of last invocation
        secondary_target_secs (float): the target we are going for for the specified time
            killer. if it doesn't use all its time and target_secs < secondary_target_secs,
            we return early
        time_killer (callable, optional): if available, a function that can be passed
            a target amount of time in seconds which might use some of it
    """

    def __init__(self, target_secs: float, secondary_target_secs: float = 0.0,
                 time_killer: typing.Callable = None):
        self.target_secs = target_secs
        self.time_killer = time_killer
        self.secondary_target_secs = secondary_target_secs
        self.last_at = None

    def __call__(self):
        if self.last_at is not None:
            dtime = time.time() - self.last_at
            if dtime < self.target_secs:
                if self.time_killer and dtime < self.secondary_target_secs:
                    self.time_killer(self.secondary_target_secs - dtime)
                    dtime = time.time() - self.last_at
                if dtime < self.target_secs:
                    time.sleep(self.target_secs - dtime)
        self.last_at = time.time()


#!/usr/bin/env python
"""UDP hole punching client."""
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import random
import string
import time
import json
from nhxpoly.nhxpoly import NewHopeXSPolyBox
from newhope import newhope
import random
import string
import sys
import pickle

# a client protocol

box = NewHopeXSPolyBox()
box.name = sys.argv[1]
box.init = False

class ClientProtocol(DatagramProtocol):
    """
    Client protocol implementation.
    The clients registers with the rendezvous server.
    The rendezvous server returns connection details for the other peer.
    The client Initializes a connection with the other peer and sends a
    message.
    """

    def startProtocol(self):
        """Register with the rendezvous server."""
        self.server_connect = False
        self.peer_init = False
        self.peer_connect = False
        self.peer_address = None
        self.transport.write('0'.encode(), ('0.0.0.0', 7654))

    def toAddress(self, data):
        #data = data#.decode()
        """Return an IPv4 address tuple."""
        data = data.decode()
        ip, port = data.split(':')
        return (ip, int(port))

    def checkFormat(self, datagram):
        if '.' in datagram and ':' in datagram:
            if len(datagram.split('.')) == 4 and len(datagram.split(':')) == 2:
                return True
        return False

    def datagramReceived(self, datagram, host):
        #print('Incoming data: ' + repr(datagram))
        """Handle incoming datagram messages."""
        """
        if not self.server_connect:
            self.server_connect = True
            self.transport.write('ok'.encode(), (rendevous_ip, rendevous_port))
            print('Connected to server, waiting for peer...')
        """
        if datagram == b'0':
            return

        if datagram == b'ok' and not self.server_connect:
            print('Successfully connected to rendezvous server')
            self.server_connect = True

        elif not self.peer_init:
            self.peer_address = self.toAddress(datagram)
            self.peer_init = True
            self.transport.write('init'.encode(), self.peer_address)
            print('Sent init to %s:%d' % self.peer_address)

        elif not self.peer_connect:
            self.peer_connect = True
            host = self.transport.getHost().host
            port = self.transport.getHost().port
            self.transport.write('0'.encode(), self.peer_address)
            if box.name == 's':
                self.transport.write(box.initCode(), self.peer_address)
                print('Sent NewHope_X25519_XSalsa20_Poly1305 init')
                box.genPrekeyChunk()
                box._state = 2

        else:
            print(box._state)
            if datagram == box.initCode():
                box.createSealedBox()
                print('Peer to peer NewHope_X25519_XSalsa20_Poly1305 key exchange started')
                self.transport.write(box.pk, self.peer_address)
                print('Sent X25519_XSalsa20_Poly1305 Sealed Box Key %s' % repr(box.pk))
                box._state = 3

            elif box._state == 2:
                box.setSenderPubKey(datagram)
                print('Recieved X25519_XSalsa20_Poly1305 Sealed Box Key %s' % repr(box.sender_nacl_pubkey))
                box.encryptPrekeyChunk()
                self.transport.write(box.enc_prekey_chunk_1, self.peer_address)
                print('Prekey chunk 1: %s' % box.prekey_chunk_1)
                print('Sent encrypted prekey chunk 1')
                box.genSeed()
                box._state = 4

            elif box._state == 3:
                box.enc_prekey_chunk_1 = datagram
                box.openSealedBox()
                print('Opened sealed box containing prekey chunk 1 %s' % box.prekey_chunk_1)
                box.genSeed()
                self.transport.write(box.seed_hash, self.peer_address)
                print('Sent shake_128 hashed HewHope commitment seed: %s' % box.seed_hash)
                box._state = 5

            elif box._state == 4:
                box.recv_hash = datagram
                self.transport.write(box.seed, self.peer_address)
                print('Recieved NewHope commitment hash: %s' % box.recv_hash)
                print('Sent NewHope raw commitment seed: %s' % box.seed)
                shaked = False
                while not shaked:
                    try:
                        box.initNewHope()
                        shaked = True
                    except Exception as e:
                        pass
                box._state = 6

            elif box._state == 5:
                box.recv_seed = datagram
                print('Recieved NewHope seed hash: %s' % box.recv_seed)
                self.transport.write(box.seed, self.peer_address)
                print('Sent clear NewHope seed')
                shaked = False
                while not shaked:
                    try:
                        box.initNewHope()
                        shaked = True
                    except Exception as e:
                        pass
                self.transport.write(pickle.dumps(box.message), self.peer_address)
                print('Sent NewHope initial message %s' % repr(box.message))
                box._state = 7

            elif box._state == 6:
                box.recv_seed = datagram
                box.verifySeed()
                print('Seeds verified')
                box._state = 8
                #send the second new hope message

            elif box._state == 7:
                box.recv_message = pickle.loads(datagram)
                print('Recieved NewHope message: %s' % repr(box.recv_message))
                box.message = newhope.shareda(box.recv_message)
                #self.transport.write(pickle.dumps(box.message), self.peer_address)
                box.createNewHopeSharedKeya()
                print('Shared key: %s' % box.shared_newhope_key)
                box.combine_prekey_chunks()
                print('Combined prekey: %s' % box.prekey)
                box._state = 9

            elif box._state == 8:
                box.recv_message = pickle.loads(datagram)
                print('Received NewHope message: %s' % repr(box.recv_message))
                box.message = newhope.sharedb(box.recv_message)
                self.transport.write(pickle.dumps(box.message), self.peer_address)
                box.createNewHopeSharedKeyb()
                print('Shared key: %s' % box.shared_newhope_key)
                box.combine_prekey_chunks()
                print('Combined prekey: %s' % box.prekey)
                box._state = 9

    def stopProtocol(self):
        print('Stopped')

if __name__ == '__main__':

    protocol = ClientProtocol()
    t = reactor.listenUDP(0, protocol)
    reactor.run()


import networkx as nx
import matplotlib.pyplot as plt

grafo = nx.Graph()

grafo.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8, 9])

def grafo_ciclo(grafo):
    conjuntoK = list(grafo.nodes())
    for indice in range(0, len(conjuntoK) - 1):
        grafo.add_edge(conjuntoK[indice], conjuntoK[indice + 1])

    grafo.add_edge(conjuntoK[len(conjuntoK) - 1], conjuntoK[0])

grafo_ciclo(grafo=grafo)

nx.draw(grafo, with_labels=True, node_color='blue')

plt.savefig('Ciclo.png')
plt.show()