Ejemplo n.º 1
0
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        con = sqlite3.connect("Launch_Data.db")
        self.cur = con.cursor()
        self.setGeometry(0, 0, 1500, 800)
        self.setWindowTitle('Моделирование движения ракеты')
        layout = QVBoxLayout(
        )  # установка стиля расположения UI элементов вертикально

        # создание интерфэйса
        # Поле для ввода широты
        self.Latitudelabel = QLabel(self)
        self.Latitudelabel.setText("Latitude")
        self.Latitudelabel.move(20, 30)
        self.Latitudelabel.resize(120, 20)
        layout.addWidget(self.Latitudelabel)

        self.LatitudeInput = QLineEdit(self)
        self.LatitudeInput.setText('70')
        self.LatitudeInput.move(80, 30)
        self.LatitudeInput.resize(125, 20)
        layout.addWidget(self.LatitudeInput)
        # при изменений значения поля ввода вызывается функция adjustLatitude
        self.LatitudeInput.textChanged.connect(self.adjustLatitude)

        # поля для ввода долготы
        self.LongitudeLabel = QLabel(self)
        self.LongitudeLabel.setText("Longitude")
        self.LongitudeLabel.move(20, 60)
        layout.addWidget(self.LongitudeLabel)

        self.LongitudeInput = QLineEdit(self)
        self.LongitudeInput.setText('-90')
        self.LongitudeInput.move(80, 60)
        self.LongitudeInput.resize(125, 20)
        layout.addWidget(self.LongitudeInput)
        self.LongitudeInput.textChanged.connect(self.adjustLongitude)

        # поля для ввода высоты над уровнем моря
        self.ElevationLabel = QLabel(self)
        self.ElevationLabel.setText("Elevation")
        self.ElevationLabel.move(20, 90)
        layout.addWidget(self.ElevationLabel)

        self.ElevationInput = QLineEdit(self)
        self.ElevationInput.setText('560')
        self.ElevationInput.move(80, 90)
        self.ElevationInput.resize(125, 20)
        layout.addWidget(self.ElevationInput)

        # поля для ввода угла наклона ракеты
        self.InclinationLabel = QLabel(self)
        self.InclinationLabel.setText("Inclination")
        layout.addWidget(self.InclinationLabel)

        self.InclinationInput = QLineEdit(self)
        self.InclinationInput.setText('85')
        layout.addWidget(self.InclinationInput)
        self.InclinationInput.textChanged.connect(self.adjustInclination)

        # поля для ввода даты запуска
        self.DateLabel = QLabel(self)
        self.DateLabel.move(20, 120)
        self.DateLabel.setText("Date")
        layout.addWidget(self.DateLabel)

        # текущяя дата
        now = datetime.datetime.now()
        self.DateInput = QDateEdit(self)
        self.DateInput.setDate(now)
        self.DateInput.move(80, 120)
        self.DateInput.resize(125, 20)
        layout.addWidget(self.DateInput)
        self.DateInput.dateTimeChanged.connect(self.adjustDate)

        # кнопка для получения графиков об атмосферных условиях в ту дату
        self.EnvironmentInfo = QPushButton("Environment")
        self.EnvironmentInfo.move(20, 150)
        layout.addWidget(self.EnvironmentInfo)
        self.EnvironmentInfo.clicked.connect(self.EnvironmentD)

        # группирование все радио кнопок для выбора ввида мотора
        self.motorgroup = QButtonGroup()

        self.m7450 = QRadioButton("Cesaroni 7450M2505")
        self.m7450.move(20, 180)
        self.motorgroup.addButton(self.m7450)
        layout.addWidget(self.m7450)
        # заранее активирование одной радио кнопки
        self.m7450.setEnabled(True)
        # каждый раз при выборе этой радикнопки вызывается функция для установки текущего выбора
        self.m7450.toggled.connect(lambda: self.setMotor(self.m7450.text()))

        self.j360 = QRadioButton("Cesaroni J360")
        self.j360.move(20, 210)
        self.motorgroup.addButton(self.j360)
        layout.addWidget(self.j360)
        self.j360.toggled.connect(lambda: self.setMotor(self.j360.text()))

        self.m1300 = QRadioButton("Cesaroni M1300")
        self.motorgroup.addButton(self.m1300)
        layout.addWidget(self.m1300)
        self.m1300.toggled.connect(lambda: self.setMotor(self.m1300.text()))

        self.m1400 = QRadioButton("Cesaroni M1400")
        self.motorgroup.addButton(self.m1400)
        layout.addWidget(self.m1400)
        self.m1400.toggled.connect(lambda: self.setMotor(self.m1400.text()))

        self.m1540 = QRadioButton("Cesaroni M1540")
        self.motorgroup.addButton(self.m1540)
        layout.addWidget(self.m1540)
        self.m1540.toggled.connect(lambda: self.setMotor(self.m1540.text()))

        self.m1670 = QRadioButton("Cesaroni M1670")
        self.motorgroup.addButton(self.m1670)
        layout.addWidget(self.m1670)
        self.m1670.toggled.connect(lambda: self.setMotor(self.m1670.text()))

        self.m3100 = QRadioButton("Cesaroni M3100")
        self.motorgroup.addButton(self.m3100)
        layout.addWidget(self.m3100)
        self.m3100.toggled.connect(lambda: self.setMotor(self.m3100.text()))

        self.j115 = QRadioButton("Hypertek J115")
        self.motorgroup.addButton(self.j115)
        layout.addWidget(self.j115)
        self.j115.toggled.connect(lambda: self.setMotor(self.j115.text()))

        # кнопка для вывода графика сопротивления со временем мотора
        self.motorinfo = QPushButton("Motor")
        layout.addWidget(self.motorinfo)
        # при нажатий вызывается функция для вывода графика
        self.motorinfo.clicked.connect(self.motorInfo)

        # группирование всех радио кнопок для выбора ракеты
        self.rocketgroup = QButtonGroup()

        self.caldene = QRadioButton("Caldene")
        self.rocketgroup.addButton(self.caldene)
        layout.addWidget(self.caldene)
        self.caldene.toggled.connect(
            lambda: self.setRocket(self.caldene.text()))
        # заранее выбор одной из радио кнопок
        self.caldene.setEnabled(True)

        # создание радио кнопок для выбора вида ракеты
        self.calisto = QRadioButton("Calisto")
        self.rocketgroup.addButton(self.calisto)
        layout.addWidget(self.calisto)
        # при выборе вызов функций меняющий текущий вид ракеты
        self.calisto.toggled.connect(
            lambda: self.setRocket(self.calisto.text()))

        self.europia = QRadioButton("Euporia")
        self.rocketgroup.addButton(self.europia)
        layout.addWidget(self.europia)
        self.europia.toggled.connect(
            lambda: self.setRocket(self.europia.text()))

        self.jiboia = QRadioButton("Jiboia")
        self.rocketgroup.addButton(self.jiboia)
        layout.addWidget(self.jiboia)
        self.jiboia.toggled.connect(lambda: self.setRocket(self.jiboia.text()))

        self.keron = QRadioButton("Keron")
        self.rocketgroup.addButton(self.keron)
        layout.addWidget(self.keron)
        self.keron.toggled.connect(lambda: self.setRocket(self.keron.text()))

        self.mandioca = QRadioButton("Mandioca")
        self.rocketgroup.addButton(self.mandioca)
        layout.addWidget(self.mandioca)
        self.mandioca.toggled.connect(
            lambda: self.setRocket(self.mandioca.text()))

        # кнопка при нажатий выдаёт график траекторий полёта ракеты
        self.trajectory = QPushButton("Trajectory")
        layout.addWidget(self.trajectory)
        self.trajectory.clicked.connect(self.GetTrajectory)

        # кнопка при нажатий выдаёт график кинематических данных полёта
        self.kinematics = QPushButton("Kinematics data")
        layout.addWidget(self.kinematics)
        self.kinematics.clicked.connect(self.GetKinematics)

        # кнопка при нажатий выдаёт график скоростный данных
        self.altitude = QPushButton("Altitude data")
        layout.addWidget(self.altitude)
        self.altitude.clicked.connect(self.GetAltitude)

        # кнопка при нажатий выдаёт график данных об энергий во время полёта
        self.energy = QPushButton("Energy Data")
        layout.addWidget(self.energy)
        self.energy.clicked.connect(self.GetEnergy)

        # "растягиваем" расположение чтобы элементы UI оказались на верхней стороне окна
        layout.addStretch(1)
        # добавляем новый стиль горизонтального расположения
        horlayout = QHBoxLayout()
        # "растягиваем" горизонтальное расположение чтобы UI оказался на правой стороне
        horlayout.addStretch(1)
        # соедениям оба стиля расположения в одно
        horlayout.addLayout(layout)
        # устанавливаем расположение
        self.setLayout(horlayout)

    # функция проверяет поле широты на попадание в диапозон -90,90 иначе меняет значение на полях
    def adjustLatitude(self):
        latitude = self.LatitudeInput.text()
        if latitude != '' and latitude != '-':
            latitude = int(latitude)
            if latitude < -90:
                self.LatitudeInput.setText("-90")
            elif latitude > 90:
                self.LatitudeInput.setText("90")

    # функция проверяет поле долготы на попадание в диапозон -180,180 иначе меняет значение на полях
    def adjustLongitude(self):
        longitude = self.LongitudeInput.text()
        if longitude != '' and longitude != '-':
            longitude = int(longitude)
            if longitude < -180:
                self.LongitudeInput.setText("-180")
            elif longitude > 180:
                self.LongitudeInput.setText("180")

    # функция проверяет поле угла наклона ракеты на попадание в диапозон 0,90 иначе меняет значение на полях
    def adjustInclination(self):
        inclination = self.InclinationInput.text()
        if inclination != '' and inclination != '-':
            inclination = int(inclination)
            if inclination < 0:
                self.InclinationInput.setText("0")
            elif inclination > 90:
                self.InclinationInput.setText("90")

    # функция проверяет введенный год на попадание в диапозон 2017,2020 иначе меняет значение года
    def adjustDate(self):
        date = self.DateInput.date()
        if date.year() < 2017:
            date.setDate(2017, date.month(), date.day())
        elif date.year() > 2020:
            date.setDate(2020, date.month(), date.day())
        self.DateInput.setDate(date)

    # функция выводящее график об атмосферных данных в введенную дату и в введенных координатах
    def EnvironmentD(self):
        self.setEnvironment()
        self.Env.info()

    # функция инициализируещее атмосферные данные в модуле Environment
    def setEnvironment(self):
        self.longitude = int(self.LongitudeInput.text())
        self.elevation = int(self.ElevationInput.text())
        self.date = self.DateInput.date()
        self.latitude = int(self.LatitudeInput.text())

        # подстраивание значений под диапозоны имеющихся данных
        if self.latitude > -90 and self.latitude < -30:
            self.Env = Environment(
                railLength=5.2,
                date=(self.date.year() - 2, self.date.month(), self.date.day(),
                      6),
                latitude=-7.5 + 3 * (-90 - self.latitude) / -60,
                longitude=324 + (2.25 * (-180 - self.longitude) / -360),
                elevation=self.elevation)
            # получение значения файла о погоде из базы данных
            weatherfile = self.cur.execute(
                '''SELECT File_Path FROM WeatherFiles WHERE File_Path LIKE "%CLBI%" AND Year=?''',
                (self.date.year(), )).fetchone()

            self.Env.setAtmosphericModel(type='Reanalysis',
                                         file=weatherfile[0],
                                         dictionary='ECMWF')
        elif self.latitude >= -30 and self.latitude < 30:
            self.Env = Environment(
                railLength=5.2,
                date=(self.date.year() - 2, self.date.month(), self.date.day(),
                      6),
                latitude=-3.75 + 5.25 * (-30 - self.latitude) / -60,
                longitude=314.25 + 3 * (-180 - self.longitude) / -360,
                elevation=self.elevation)

            weatherfile = self.cur.execute(
                '''SELECT File_Path FROM WeatherFiles WHERE File_Path LIKE "%Alcantara%" AND Year=?''',
                (self.date.year(), )).fetchone()

            self.Env.setAtmosphericModel(type='Reanalysis',
                                         file=weatherfile[0],
                                         dictionary='ECMWF')
        elif self.latitude >= 30 and self.latitude <= 90:
            self.Env = Environment(
                railLength=5.2,
                date=(self.date.year() - 2, self.date.month(), self.date.day(),
                      6),
                latitude=31.5 + 3 * (90 - self.latitude) / 60,
                longitude=252 + 2.25 * (-180 - self.longitude) / -360,
                elevation=self.elevation)
            weatherfile = self.cur.execute(
                '''SELECT File_Path FROM WeatherFiles WHERE File_Path LIKE "%Spaceport%" AND Year=?''',
                (self.date.year(), )).fetchone()

            self.Env.setAtmosphericModel(type='Reanalysis',
                                         file=weatherfile[0],
                                         dictionary='ECMWF')

    # функция назначает имя текущего выбранного мотора из группы радиокнопок
    def setMotor(self, name):
        name = name.split()
        name = '_'.join(name)
        self.motorName = name

    # функция инициализирует модель ракеты внутри модуля SolidMotor
    def setMotorModel(self):
        motorfile = self.cur.execute(
            'SELECT File_Path FROM Motors WHERE Motor_Name=?',
            (self.motorName, )).fetchone()
        motorfile = str(motorfile[0])
        self.motor_model = SolidMotor(thrustSource=motorfile,
                                      burnOut=3.9,
                                      grainNumber=5,
                                      grainSeparation=5 / 1000,
                                      grainDensity=1815,
                                      grainOuterRadius=33 / 1000,
                                      grainInitialInnerRadius=15 / 1000,
                                      grainInitialHeight=120 / 1000,
                                      nozzleRadius=33 / 1000,
                                      throatRadius=11 / 1000,
                                      interpolationMethod='linear')

    # функция выводит график сопротивления мотора
    def motorInfo(self):
        self.setMotorModel()
        self.motor_model.info()

    # функция назначает текущее имя выбранного типа ракеты
    def setRocket(self, name):
        self.rocketName = name

    # функция инициализирует модель ракеты с помощью модуля Rocket
    def setRocketModel(self):
        self.inclination = int(self.InclinationInput.text())
        # получение файла толчка из базы данных
        thrustcurve = self.cur.execute(
            'SELECT File_Path FROM Rockets WHERE Rocket_Name=?',
            (self.rocketName, )).fetchone()
        thrustcurve = str(thrustcurve[0])
        self.RocketModel = Rocket(
            motor=self.motor_model,
            radius=127 / 2000,
            mass=19.197 - 2.956,
            inertiaI=6.60,
            inertiaZ=0.0351,
            distanceRocketNozzle=-1.255,
            distanceRocketPropellant=-0.85704,
            powerOffDrag="data/calisto/powerOffDragCurve.csv",
            powerOnDrag=thrustcurve)
        self.RocketModel.setRailButtons([0.2, -0.5])
        # добавление деталей в модель ракеты по модулю Rocket
        NoseCone = self.RocketModel.addNose(length=0.55829,
                                            kind="vonKarman",
                                            distanceToCM=0.71971)

        FinSet = self.RocketModel.addFins(4,
                                          span=0.100,
                                          rootChord=0.120,
                                          tipChord=0.040,
                                          distanceToCM=-1.04956)

        Tail = self.RocketModel.addTail(topRadius=0.0635,
                                        bottomRadius=0.0435,
                                        length=0.060,
                                        distanceToCM=-1.194656)
        # добавление парашютов
        Main = self.RocketModel.addParachute('Main',
                                             CdS=10.0,
                                             trigger=self.mainTrigger,
                                             samplingRate=105,
                                             lag=1.5,
                                             noise=(0, 8.3, 0.5))

        Drogue = self.RocketModel.addParachute('Drogue',
                                               CdS=1.0,
                                               trigger=self.drogueTrigger,
                                               samplingRate=105,
                                               lag=1.5,
                                               noise=(0, 8.3, 0.5))

        self.TestFlight = Flight(rocket=self.RocketModel,
                                 environment=self.Env,
                                 inclination=self.inclination,
                                 heading=0)

    # функции активаций парашютов
    def drogueTrigger(self, p, y):
        return True if y[5] < 0 else False

    def mainTrigger(self, p, y):
        return True if y[5] < 0 and y[2] < 800 else False

    # функция выдаёт траекторию ракеты
    def GetTrajectory(self):
        self.setMotorModel()
        self.setEnvironment()
        self.setRocketModel()
        self.TestFlight.plot3dTrajectory()

    # функция выдаёт график кинематических данных
    def GetKinematics(self):
        self.setMotorModel()
        self.setEnvironment()
        self.setRocketModel()
        self.TestFlight.plotLinearKinematicsData()

    # функция выдаёт график скоростных данных
    def GetAltitude(self):
        self.setMotorModel()
        self.setEnvironment()
        self.setRocketModel()
        self.TestFlight.plotAttitudeData()

    # функция выдаёт график энергий во время полёта
    def GetEnergy(self):
        self.setMotorModel()
        self.setEnvironment()
        self.setRocketModel()
        self.TestFlight.plotEnergyData()
Ejemplo n.º 2
0
class Addstocks(QWidget):

    def __init__(self, pf):
        self.counter = 0
        self.pf = pf
        super(Addstocks, self).__init__()
        self.setMinimumSize(QSize(300, 230))
        self.resize(550, 320)
        self.setWindowTitle("Add stocks")

        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.darkCyan)  # darkcyan
        self.setPalette(p)

        label1 = QLabel("Enter a stock ticker:", self)
        self.ticker = QLineEdit(self)
        self.ticker.move(270, 20)
        self.ticker.resize(200, 32)
        label1.move(20, 25)

        label2 = QLabel("How many shares?", self)
        self.amount = QLineEdit(self)
        self.amount.move(270, 80)
        self.amount.resize(200, 32)
        label2.move(20, 85)

        label3 = QLabel("When you bought it?", self)
        self.date = QDateEdit(self)
        self.date.move(270, 140)
        self.date.resize(200, 32)
        self.date.setDate(QDate.currentDate())

        label3.move(20, 145)
        self.date.editingFinished.connect(self.date_method)

        pybutton = QPushButton('Add a stock', self)
        pybutton.clicked.connect(self.click)
        pybutton.resize(200, 32)
        pybutton.move(270, 200)

        pybutton2 = QPushButton('Finished', self)
        pybutton2.clicked.connect(self.click1)
        pybutton2.resize(200, 32)
        pybutton2.move(270, 260)

    def date_method(self):
        # Change the date received by the user into a correct form
        self.counter += 1
        value = self.date.date()
        self.day = value.toPyDate()

    def click(self):
        # Finds the ticker from Yahoo Finance and checks that the number of stocks owned is legit.
        # Also checks that the date chosen is a legitimate.
        # self.counter is used because editingFinished.connect does not work if the user does not touch the
        # date picker at all. Thus, the program needs to have a date even though the date_method has not been
        # activated.
        if self.counter == 0:
            value = QDate.currentDate()
            self.day = value.toPyDate()
        today = date.today()
        delta = today - self.day
        if delta.days < 0:
            QMessageBox.about(self, "Error", "The date you gave is incorrect.")
        else:
            self.stock = self.ticker.text()
            self.am = self.amount.text()
            tc = yf.Ticker(self.stock)
            pricedata = tc.history(period='5y')['Close']
            if len(pricedata) > 0:
                try:
                    self.am = float(self.am)
                    if self.am < 0.01:
                        QMessageBox.about(self, "Error", "Incorrect amount!")
                    else:
                        self.pf.add_stock(self.stock, self.am, self.day)
                        QMessageBox.about(self, "Success", "Stock added!")
                        self.amount.clear()
                        self.ticker.clear()
                except ValueError:
                    QMessageBox.about(self, "Error", "Incorrect amount!")

            else:
                QMessageBox.about(self, "Error", "Did not find any data for that stock.")

    def click1(self):
        #counts the different ratios for the portfolio and launches the new window
        self.pf.pf_value()
        self.pf.pf_returns()
        self.pf.get_greeks()
        self.pf.count_sharpe()
        self.next_window = Infopage(self.pf)
        self.next_window.show()
        self.close()
Ejemplo n.º 3
0
class MainApp(QMainWindow):
    """Esta será la aplicación principal"""
    def __init__(self, parent=None, *args):
        super(MainApp, self).__init__(parent=parent)
        '''
		configuración de la pantalla
		'''
        self.setFixedSize(
            850,
            600)  #El tamaño por defecto de la pantalla sin permitir ajustes
        self.setWindowTitle("Parámetros de la fotografía aérea"
                            )  #Establece el título de la ventana
        self.setStyleSheet("background-color: rgb(85, 255, 127)"
                           )  #Establece el color de fondo
        self.setWindowIcon(QIcon(
            "iconos/main_window.png"))  #se establece un ícono para la pantalla
        '''
		Configuración del título
		'''
        self.label_t = QLabel("Definir los parámetros de la fotografía aérea",
                              self)  #instanciamos un label
        self.label_t.setGeometry(
            0, 20, 800, 40)  #definimos las propiedades geométricas del label
        self.label_t.setAlignment(
            Qt.AlignHCenter)  #Aliniamos el label en el centro de la pantalla
        self.label_t.setFont(QFont(
            'Times', 24))  #Definimos la fuente del texto del label
        '''
		Configuración de los labels e inputs
		'''

        #label 1 entidad
        self.label_e = QLabel("Entidad de donde proviene la fotografía:", self)
        self.label_e.setGeometry(50, 100, 800, 30)
        self.label_e.setAlignment(Qt.AlignLeft)
        self.label_e.setFont(QFont('Times', 12))
        #input 1 entidad
        self.input_e = QLineEdit(
            self)  #instanciamos un objeto para realizar una entrada
        self.input_e.move(600, 100)  #movemos el input a estas coordenadas
        self.input_e.resize(200, 25)  #Definimos el tamaño de el campo de texto
        self.input_e.setStyleSheet(
            "background-color: #fff")  #el color del campo de texto será blanco
        self.input_e.setMaxLength(
            50)  #definimos la cantidad maxima de carácteres a recibir

        #label 2 número de vuelo
        self.label_n_v = QLabel("Número de vuelo:", self)
        self.label_n_v.setGeometry(50, 150, 800, 30)
        self.label_n_v.setAlignment(Qt.AlignLeft)
        self.label_n_v.setFont(QFont('Times', 12))
        #input 2 número de vuelo
        self.input_n_v = QLineEdit(self)
        self.input_n_v.move(600, 150)
        self.input_n_v.resize(200, 25)
        self.input_n_v.setStyleSheet("background-color: #fff")
        self.input_n_v.setValidator(
            QIntValidator(0, 30000, self)
        )  #Validamos que solo se acepten valores numéricos con un rango de 0 a 30000

        #label 3 faja de vuelo
        self.label_f_v = QLabel("Faja de vuelo:", self)
        self.label_f_v.setGeometry(50, 200, 800, 30)
        self.label_f_v.setAlignment(Qt.AlignLeft)
        self.label_f_v.setFont(QFont('Times', 12))
        #input 3 faja de vuelo
        self.input_f_v = QLineEdit(self)
        self.input_f_v.move(600, 200)
        self.input_f_v.resize(200, 25)
        self.input_f_v.setStyleSheet("background-color: #fff")
        self.input_f_v.setMaxLength(50)

        #label 4 escala de la fotografía
        self.label_e_f = QLabel("Escala de la fotografía 1:", self)
        self.label_e_f.setGeometry(50, 250, 800, 30)
        self.label_e_f.setAlignment(Qt.AlignLeft)
        self.label_e_f.setFont(QFont('Times', 12))
        #input 4 escala de la fotografía
        self.input_e_f = QLineEdit(self)
        self.input_e_f.move(600, 250)
        self.input_e_f.resize(200, 25)
        self.input_e_f.setStyleSheet("background-color: #fff")
        self.input_e_f.setValidator(QIntValidator(0, 300000, self))

        #label 5 altura del vuelo
        self.label_a_v = QLabel("Altura del vuelo (en metros):", self)
        self.label_a_v.setGeometry(50, 300, 800, 30)
        self.label_a_v.setAlignment(Qt.AlignLeft)
        self.label_a_v.setFont(QFont('Times', 12))
        #input 5 altura del vuelo
        self.input_a_v = QLineEdit(self)
        self.input_a_v.move(600, 300)
        self.input_a_v.resize(200, 25)
        self.input_a_v.setStyleSheet("background-color: #fff")
        self.input_a_v.setValidator(QIntValidator(0, 300000, self))

        #label 6 distancia focal
        self.label_d_f = QLabel("Distancia focal:", self)
        self.label_d_f.setGeometry(50, 350, 800, 30)
        self.label_d_f.setAlignment(Qt.AlignLeft)
        self.label_d_f.setFont(QFont('Times', 12))
        #input 6 distancia focal
        self.input_d_f = QLineEdit(self)
        self.input_d_f.move(600, 350)
        self.input_d_f.resize(200, 25)
        self.input_d_f.setStyleSheet("background-color: #fff")
        self.input_d_f.setValidator(QDoubleValidator(0.0, 1000000.0, 4, self))

        #label 7 altura del terreno sobre el nivel del mar
        self.label_a_t_m = QLabel("Altura del terreno/nivel del mar:", self)
        self.label_a_t_m.setGeometry(50, 400, 800, 30)
        self.label_a_t_m.setAlignment(Qt.AlignLeft)
        self.label_a_t_m.setFont(QFont('Times', 12))
        #input 7 altura del terreno sobre el nivel del mar
        self.input_a_t_m = QLineEdit(self)
        self.input_a_t_m.move(600, 400)
        self.input_a_t_m.resize(200, 25)
        self.input_a_t_m.setStyleSheet("background-color: #fff")
        self.input_a_t_m.setValidator(QIntValidator(0, 300000, self))

        #label 8 fecha en que se tomn_v la fotografía
        self.label_f_f = QLabel("Fecha en que se tomó la fotografía:", self)
        self.label_f_f.setGeometry(50, 450, 800, 30)
        self.label_f_f.setAlignment(Qt.AlignLeft)
        self.label_f_f.setFont(QFont('Times', 12))
        #input 8 fecha en que se tomó la fotografía
        self.input_f_f = QDateEdit(self)
        self.input_f_f.move(600, 450)
        self.input_f_f.resize(200, 25)
        self.input_f_f.setStyleSheet("background-color: #fff")
        '''
		configuración del boton
		'''
        #boton de aceptar
        self.btn_acept = QPushButton("Aceptar", self)  #instanciamos un boton
        self.btn_acept.setGeometry(0, 0, 100, 50)
        self.btn_acept.move(375, 500)
        self.btn_acept.setStyleSheet("background-color: rgb(255, 255, 0)")
        self.btn_acept.clicked.connect(
            self.slot_aceptar
        )  #definimos que evento realizará al ser presionado

        self.label_er = QLabel(
            "", self
        )  #definimos un label de error en caso de no todos los campos estén llenos
        self.label_er.setGeometry(20, 575, 800, 30)
        self.label_er.setAlignment(Qt.AlignHCenter)
        self.label_er.setFont(QFont('Times', 12))
        self.label_er.setStyleSheet("color: red")

        #Este es el evento que se va a ejecutar si se da en aceptar
    def slot_aceptar(self):
        #Creamos una lista con los textos de los campos para verificiar si están vacíos o no
        self.campos = []
        self.campos.extend([
            self.input_e.text(),
            self.input_n_v.text(),
            self.input_f_v.text(),
            self.input_e_f.text(),
            self.input_a_v.text(),
            self.input_d_f.text(),
            self.input_a_t_m.text(),
            self.input_f_f.text()
        ])

        #Recorremos la lista anteriormente creada
        for i in self.campos:
            '''
			ya que cada valor de i es un texto podemos preguntar si ese texto esta vacío o no
			de tal forma que aquí preguntamos si el texto es falso, es decir no hay texto, entonces
			mande un mensaje de error
			'''
            if not i:
                return self.label_er.setText(
                    "Uno o más campos están vacíos, Vuelve a intentarlo")
        else:
            '''
			Una vez verificado que los campos están llenos, validamos que el valor de la altura 
			del terreno sobre el mar es mayor a la altura de la fotografía, si esto no es así
			mandamos un mensaje de error pidiendo que se ingresen valores validos
			'''
            if int(self.campos[4]) >= int(self.campos[-2]):
                return self.label_er.setText(
                    "La altura del vuelo no puede ser mayor o igual a la altura del terreno sobre  el mar"
                )
            else:
                #Creamos un objeto de tipo CalApp para posteriormente mostrarla
                self.w = CalApp(
                    self.campos)  #Mandamos la lista de campos como parámetro
                self.w.show()  #mostramos la pantalla
 def create_date_edit(window, x, pos):
     date_edit = QDateEdit(self)
     date_edit.move(x, y_gap + pos * y_step)
     date_edit.resize(150, 24)
     return date_edit