# To add a new cell, type '# %%'
# To add a new markdown cell, type '# %% [markdown]'
# %%
import sys
sec_f = 24
from vinyl_srw.srwlib import *
from vinyl_srw.uti_plot import *
from scipy.ndimage.interpolation import zoom
import os
import numpy as np
import pandas as pd
from itertools import islice
from scipy.interpolate import interp1d
from scipy.interpolate import interp2d
from scipy.misc import electrocardiogram
from scipy.signal import find_peaks,peak_widths
import os.path as path
from scipy.interpolate import CubicSpline
import matplotlib.pyplot as plt
from config import get_from_config, save_to_config
import fur.path_assistant as path_assistant
srw_dir = path_assistant.get_srw_precalculated_spectrum_dir()

# %%
#fundamental constants
qe = get_from_config("e")
c = get_from_config("c_m/s")
me = get_from_config("me_kg")
hc = get_from_config("hc_um_eV")

# %%
undulator_Krms_vs_gap_mm = pd.read_csv(srw_dir.fi("Krms_vs_gap.csv"), header=None, skiprows=3).iloc[:,[0,1]]
undulator_Krms_vs_gap_mm = undulator_Krms_vs_gap_mm.rename(columns={0:"gap_mm",1:"K_rms"})
undulator_Krms_vs_gap_mm = undulator_Krms_vs_gap_mm[undulator_Krms_vs_gap_mm["K_rms"].notna()]

# %%
undulator_Krms_vs_gap_mm["K_peak"] = np.sqrt(2)*undulator_Krms_vs_gap_mm["K_rms"]
Kund = np.interp(get_from_config("Undulator_Gap_mm"),
                 undulator_Krms_vs_gap_mm["gap_mm"],
                 undulator_Krms_vs_gap_mm["K_peak"])
print("Kund = {:.4f}".format(Kund))
save_to_config("K_peak", Kund)

# %% [markdown]
# From FEL2012 paper:

# %%
from IPython.display import Image
import fur.path_assistant as path_assistant
srw_dir = path_assistant.get_srw_precalculated_spectrum_dir()
Image(filename=srw_dir.fi("SLAC_undulator_I2.png"))

# %%
undulator_I2_gauss_cm2_df = pd.read_csv(srw_dir.fi("SLAC_undulator_I2.csv"), header=None)
K_und_paper = 2.0722
coef_to_x = qe/get_from_config("gamma")/me/c*0.01**2*1e-4*Kund/K_und_paper
undulator_x_m = coef_to_x*undulator_I2_gauss_cm2_df.iloc[:,1].values

# %%
#**********************Undulator constants:
numPer = 10 #6#Number of ID Periods (without counting for terminations; semi-integer => symmetric vs long. pos.; to allow harmonics to be symmetric or anti-symmetric?)
undPer = get_from_config("Undulator_period_m") #0.1106 #Period Length [m]
phBy = 0 #Initial Phase of the Vertical field component
Lund = numPer*undPer#1.7675
By = Kund*(2*np.pi*me*c)/(qe*undPer)#0.1514815555529875

part = SRWLParticle()
part.x = 0.0 #Initial Transverse Coordinates (initial Longitudinal Coordinate will be defined later on) [m]
part.y = 0.0
#part.z = -0.5*(numPer + 4)*undPer #Initial Longitudinal Coordinate (set 2 periods before pickup)
part.z = -0.5*(numPer + 4)*undPer #- 1.3981378
part.xp = 0 #Initial Transverse Velocities
part.yp = 0
part.gamma = get_from_config("gamma")
print("gamma = ", part.gamma) #Relative Energy
part.relE0 = 1 #Electron Rest Mass
part.nq = -1 #Electron Charge

npTraj = 20000 #Number of Points for Trajectory calculation
dispBy = array('d', [0]*npTraj)
partTraj = SRWLPrtTrj(_arBy=dispBy) #you can consider it as a part of allocation, values of B field are still zero here
partTraj.partInitCond = part
partTraj.allocate(npTraj, False)
partTraj.ctStart = 0.0 #Start Time for the calculation
#partTraj.ctEnd = fmult*undPer*(numPer+4) #End Time ~1.2166
#partTraj.ctEnd = undPer*(numPer+4)/2+1.3981378+3*zdcent_f
partTraj.ctEnd = undPer*(numPer+4) #+1.#+3*zdcent_f

lmb_0 = undPer/(2*part.gamma**2)*(1 + Kund**2/2.0)
print("lambda1_um = {}".format(lmb_0))

# %%
#***********Magnetic Field
sBy = 1 #Symmetry of the Vertical field component vs Longitudinal position
xcID = 0 #Transverse Coordinates of Undulator Center [m]
ycID = 0
zcID = 0 #Longitudinal Coordinate of Undulator Center [m]
und = SRWLMagFldU([SRWLMagFldH(1, 'v', By, phBy, sBy, 1)], undPer, numPer) #Planar Undulator
magFldCnt = SRWLMagFldC([und], array('d', [xcID]), array('d', [ycID]), array('d', [zcID])) #Container of all Field Elements

# %%
partTraj = srwl.CalcPartTraj(partTraj, magFldCnt, [1])# why was the last argument 0 and not [1] or something like this

arX = np.asarray(partTraj.arX)
arZ = np.asarray(partTraj.arZ)
arXp = np.asarray(partTraj.arXp)
arZp = np.asarray(partTraj.arZp)

ct_list = np.linspace(partTraj.ctStart, partTraj.ctEnd, partTraj.np)-np.mean((partTraj.ctStart, partTraj.ctEnd))

# %%
fig,ax = plt.subplots(figsize=[15,7])
plt.plot(ct_list,-arX*1e6,linewidth=2,color = 'b',label='Our SRW model')
plt.plot(-0.015+undulator_I2_gauss_cm2_df.iloc[:,0],
undulator_x_m*1e6,linewidth=2,color='brown',label='Simulation from THPD12 (FEL2012)')
legend = ax.legend(loc='bottom right', shadow=True, fontsize=20, frameon=True)
ax.set_xlabel('c t (m)', fontsize=20)
ax.set_ylabel('x ($\mu$m)', fontsize=20)
plt.title('Electron trajectory in the undulator', fontsize=23)
plt.tick_params(axis='both', which='major', labelsize=16)
#plt.tick_params(axis='both', which='minor', labelsize=16)
ax.grid(color='k', linestyle='-', linewidth=2, alpha=0.1)
frame = legend.get_frame()
frame.set_facecolor('0.8')
ax.set_xlim(-0.5,0.5)
for label in legend.get_lines():
       label.set_linewidth(2)  # the legend line width
plt.show()

# %%
#***********Electron Beam
f_ring = 7.5e6
Iavg_se = qe*f_ring

elecBeam = SRWLPartBeam()
elecBeam.Iavg = Iavg_se #Average Current [A]
elecBeam.partStatMom1 = part

Iavg_se

# %%
#***********Precision Parameters for SR calculation
meth = 1 #SR calculation method: 0- "manual", 1- "auto-undulator", 2- "auto-wiggler"
relPrec = 0.01 #relative precision
zStartInteg = 0 #longitudinal position to start integration (effective if < zEndInteg)
zEndInteg = 0 #longitudinal position to finish integration (effective if > zStartInteg)
useTermin = 1 #Use "terminating terms" (i.e. asymptotic expansions at zStartInteg and zEndInteg) or not (1 or 0 respectively)
sampFactNxNyForProp = 0 #sampling factor for adjusting nx, ny (effective if > 0)
arPrecPar = [meth, relPrec, zStartInteg, zEndInteg, npTraj, useTermin, sampFactNxNyForProp]
rad_mesh = get_from_config("radiation_mesh")
xs = rad_mesh[0][0]
xf = rad_mesh[0][1]
ys = rad_mesh[1][0]
yf = rad_mesh[1][1]
zobs = get_from_config("z_obs_m")
xbins = rad_mesh[0][2]
ybins = rad_mesh[1][2]
ls = rad_mesh[2][0]
lf = rad_mesh[2][1]
lbins = rad_mesh[2][2]
l_list = np.linspace(ls, lf, lbins)
Ex_3D = np.zeros(shape=(lbins, ybins, xbins), dtype=complex)
Ey_3D = np.zeros(shape=(lbins, ybins, xbins), dtype=complex)
coef = zobs*np.sqrt(1e9*qe/Iavg_se)

# %%
def to_2D(values_1D):
    np_E = np.asarray(values_1D)
    np_E_Real = np_E[::2].reshape((ybins,xbins))
    np_E_Imag = np_E[1::2].reshape((ybins,xbins))
    return np_E_Real+1j*np_E_Imag

# %%
from IPython.display import clear_output
for k, l in enumerate(l_list):
    print('Working on {} out of {}'.format(k+1, len(l_list)),' ... ')
    wfr2 = SRWLWfr() #For intensity distribution at fixed photon energy
    wfr2.allocate(1, xbins, ybins) #Numbers of points vs Photon Energy, Horizontal and Vertical Positions
    wfr2.mesh.zStart = zobs #Longitudinal Position [m] at which SR has to be calculated
    wfr2.mesh.xStart = xs #Initial Horizontal Position [m]
    wfr2.mesh.xFin = xf #Final Horizontal Position [m]
    wfr2.mesh.yStart = ys #Initial Vertical Position [m]
    wfr2.mesh.yFin = yf #Final Vertical Position [m]
    wfr2.partBeam = elecBeam
    pe = hc/l
    wfr2.mesh.eStart = pe #Initial Photon Energy [eV]
    wfr2.mesh.eFin =  pe #Final Photon Energy [eV]
    srwl.CalcElecFieldSR(wfr2, partTraj, magFldCnt, arPrecPar)
    Ex_3D[k,:,:] = coef/np.sqrt(l)*to_2D(wfr2.arEx)
    Ey_3D[k,:,:] = coef/np.sqrt(l)*to_2D(wfr2.arEy)
    clear_output(wait=True)
print("Done.")

# %%
dx = (xf-xs)/(xbins-1)
dy = (yf-ys)/(ybins-1)
dl = (l_list[-1]-l_list[0])/(lbins-1)

# %%
dx/zobs*dy/zobs*dl*np.sum(np.absolute(Ex_3D)**2)

# %%
dx/zobs*dy/zobs*dl*np.sum(np.absolute(Ey_3D)**2)

# %%
dx/zobs*dy/zobs*dl*np.sum(np.absolute(Ex_3D)**2+np.absolute(Ey_3D)**2)

apply_spectral_transmittion_function = False
print( "apply_spectral_transmittion_function = ", apply_spectral_transmittion_function)
if apply_spectral_transmittion_function:
    from wiggler_radiation.transmission_data import transmission_function
    spectral_transmission = np.sqrt(transmission_function(l_list))
    Ex_3D = spectral_transmission[:, None, None]*Ex_3D
    Ey_3D = spectral_transmission[:, None, None]*Ey_3D

# %%
import fur.path_assistant as path_assistant
np.save(path_assistant.srw_Ex_3D_file_path, Ex_3D)
np.save(path_assistant.srw_Ey_3D_file_path, Ey_3D)

# %%


# -*- coding: utf-8 -*-
# @Author: ander
# @Date:   2020-12-22 16:19:51
# @Last Modified by:   ander
# @Last Modified time: 2020-12-22 16:25:49
import pdfplumber
from PyPDF2 import PdfFileReader, PdfFileWriter, PdfFileMerger
import os.path
from .utilities import mkdir

class PDFBot(object):
    """docstring for ExcelBot"""

    def __init__(self):
        self.page_num = 0

    def open(self, file_path):
        self.filename, _ = os.path.splitext(os.path.basename(file_path))
        self.pdf = pdfplumber.open(file_path)
        self.pdf_reader = PdfFileReader(file_path)
        self.page_num = self.pdf_reader.getNumPages()

    def get_text(self, page):
        pdf_page = self.pdf.pages[page]
        return pdf_page.extract_text()

    def split(self, page, folder):
        mkdir(folder)
        pdf_writer = PdfFileWriter()
        pdf_writer.addPage(self.pdf_reader.getPage(page))
        with open(os.path.join(folder, f"{self.filename}-p{page}.pdf"), "wb") as out:
            pdf_writer.write(out)

    def merge(self, pdfs, merged_name):
        merger = PdfFileMerger()
        for pdf in pdfs:
            merger.append(PdfFileReader(pdf))
        merger.write(f"{merged_name}.pdf")


import os, sys, time
import tensorlayer as tl
from glob import glob
import time
sys.path.append(os.getcwd())

import numpy as np
import tensorflow as tf
import argparse

import tflib
import tflib.plot
import tflib.save_images_hm
import tflib.ops.batchnorm
import tflib.ops.conv2d
import tflib.ops.deconv2d
import tflib.ops.linear
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.layers import Input, Conv2D, GlobalAveragePooling2D, Dropout
from tensorflow.python.keras.layers import Activation, BatchNormalization, add, Reshape
from tensorflow.python.keras.layers import DepthwiseConv2D
slim = tf.contrib.slim
from tensorflow.python.keras import backend as K
NORMALIZE_CONST=201.
TRANSPOSE=False
act_fn_switch=tf.nn.leaky_relu

class rgan(object):
    def __init__(self, z_dim=128, nf=128,
                 training=False,images=None, latent_vec=None,reuse=None):
        with tf.variable_scope('wgan'):
            if reuse:
                tf.get_variable_scope().reuse_variables()

            self.bn_params = {
                "decay": 0.99,
                "epsilon": 1e-5,
                "scale": True,
                "is_training": training
            }
            self.mean_vec=np.load("mean.npz")["arr_0"]
            self.z_dim = z_dim
            self.w = 31
            self.h = 10
            self.c =512
            self.nf = nf
            self.restime = 3

            if latent_vec==None:
                self.z = tf.placeholder(tf.float32, shape=[None, self.z_dim])
            else:
                self.z=latent_vec
            self.x_p = self.generate(self.z)

            if images==None:
                self.pre_x = tf.placeholder(tf.float32, shape=[None, self.h,self.w,self.c])
            else:
                self.pre_x=images
            self.x=self.pre_x-self.mean_vec.reshape([1,1,1,self.mean_vec.shape[0]])
            #self.x += tf.random_normal(shape=tf.shape(self.x), mean=0.0, stddev=0.01)
            self.z_p = self.invert(self.x)

            self.dis_x = self.discriminate(self.x)
            self.dis_x_p = self.discriminate(self.x_p,reuse=True)
            self.rec_x = self.generate(self.z_p,reuse=True)
            self.rec_x_out = self.generate(self.z_p,reuse=True)+self.mean_vec.reshape([1,1,1,self.mean_vec.shape[0]])
            self.rec_z = self.invert(self.x_p,reuse=True)
            self.rec_x_p_out = self.generate(self.z,reuse=True)+self.mean_vec.reshape([1,1,1,self.mean_vec.shape[0]])

    def _residual_block(self, X, nf_output, resample, kernel_size=[3,3],upsample_shape=None, name='res_block'):
        with tf.variable_scope(name):
            input_shape = X.shape
            nf_input = input_shape[-1]
            """
            if input_shape[1]<kernel_size[0] or input_shape[2] < kernel_size[1]:
                X= tf.image.resize_image_with_crop_or_pad(X, kernel_size[0], kernel_size[1])
            """
            nf_input = input_shape[-1]
            if resample == 'down':
                shortcut = slim.avg_pool2d(X, [2,2])
                shortcut = slim.conv2d(shortcut, nf_output, kernel_size=[1,1], activation_fn=None)

                net = slim.layer_norm(X, activation_fn=act_fn_switch)
                net = slim.conv2d(net, nf_input, kernel_size=kernel_size, biases_initializer=None)
                net = slim.layer_norm(net, activation_fn=act_fn_switch)
                net = slim.conv2d(net, nf_output, kernel_size=kernel_size)
                net = slim.avg_pool2d(net, [2,2])

                return net + shortcut
            elif resample == 'up':
                if upsample_shape==None:
                    upsample_shape = tuple(int(x)*2 for x in input_shape[1:3])
                #shortcut = tf.image.resize_nearest_neighbor(X, upsample_shape, alig)
                shortcut = tf.image.resize_bilinear(X, upsample_shape)
                shortcut = slim.conv2d(shortcut, nf_output, kernel_size=[1,1], activation_fn=None)

                net = slim.batch_norm(X, activation_fn=act_fn_switch, **self.bn_params)
                #net = tf.image.resize_nearest_neighbor(net, upsample_shape)
                net = tf.image.resize_bilinear(net, upsample_shape)
                net = slim.conv2d(net, nf_output, kernel_size=kernel_size, biases_initializer=None)
                net = slim.batch_norm(net, activation_fn=act_fn_switch, **self.bn_params)
                net = slim.conv2d(net, nf_output, kernel_size=kernel_size)

                return net + shortcut
            else:
                raise Exception('invalid resample value')

    def generate(self, z, reuse=False):
        with tf.variable_scope('generate', reuse=reuse):
            start_coef = 2**(self.restime-1)
            nf = self.nf
            if TRANSPOSE:
                startdimw = 2*2**(4-self.restime)#for h= 512,w=31,c=10
                startdimh = 32*2**(4-self.restime)#for h= 512,w=31,c=10
            else:
                startdimw = 4*2**(3-self.restime)
                startdimh = 4*2**(3-self.restime)
                upsample_shapes=[
                (4,6),
                (7,16),
                (10,31)
                ]
            net = slim.fully_connected(z, startdimh*startdimw*start_coef*nf, activation_fn=None)
            net = tf.reshape(net, [-1, startdimh, startdimw, start_coef*nf])
            for i,p in enumerate(range(self.restime-1,-1,-1)):
                net = self._residual_block(net, (2**p)*nf,upsample_shape=(None if TRANSPOSE else upsample_shapes[i]), resample='up', name='res_block%d'%i)
            net = slim.batch_norm(net, activation_fn=act_fn_switch, **self.bn_params)
            #net = slim.conv2d(net, self.c, kernel_size=[3,3], activation_fn=tf.nn.tanh)
            net = slim.conv2d(net, self.c, kernel_size=[3,3], activation_fn=None)
            if TRANSPOSE:
                net = net[:,:,:-1,:]
            """
            else:
                net = net[:,11:21,:-1,:]
            """

            return net

    def discriminate(self, X, reuse=False):
        with tf.variable_scope('discriminate', reuse=reuse):
            nf = self.nf
            net = slim.conv2d(X, nf, [3,3], activation_fn=None)
            for i,p in enumerate(range(1,self.restime)):
                net = self._residual_block(net, (2**p)*nf, resample='down', name='res_block%d'%i)
            net = self._residual_block(net, (2**self.restime)*nf, resample='down', name='res_block%d'%self.restime)
            net=act_fn_switch(net)
            net=tf.reduce_mean(net,axis=[1,2])
            net = slim.fully_connected(net, 1, activation_fn=None)
            return net

    def invert(self, x,reuse=False):
        with tf.variable_scope('invert', reuse=reuse):
            nf = self.nf
            net = slim.conv2d(x, nf, [3,3], activation_fn=None)
            for i,p in enumerate(range(1,self.restime)):
                net = self._residual_block(net, (2**p)*nf, resample='down', name='res_block%d'%i)
            net=act_fn_switch(net)
            net=tf.reduce_mean(net,axis=[1,2])
            net = slim.fully_connected(net, nf*(2**(self.restime-1)), activation_fn=None)
            net = slim.fully_connected(net, self.z_dim, activation_fn=None)

            return net

    def generate_featuremap_from_noise(self,sess,noise):
        samples = sess.run(self.x_p, feed_dict={self.z: noise})
        return samples

    def generate_noise_from_featuremap(self,sess,featuremap,images=None):
        if images==None:
            samples = sess.run(self.z_p, feed_dict={self.pre_x: featuremap})
        else:
            real_image = featuremap
            samples = sess.run(self.z_p, feed_dict={images: real_image})
        return samples

    def reconstruct_featuremap(self,sess,featuremap):
        reconstructions = sess.run(self.rec_x_out, feed_dict={self.pre_x: featuremap})
        return reconstructions

def get_saver():
    train_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=tf.contrib.framework.get_name_scope())
    ssd_var_list=[v for v in train_vars if v.name.split("/")[0].startswith("wgan")]
    saver = tf.train.Saver(var_list=ssd_var_list)
    return saver


import math

x = int(input())
for i in range(x):
    x1, y1, r1, x2, y2, r2 = map(int, input().split())
    d = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
    if d == 0:
        if r1 == r2:
            print('-1')
        else:
            print('0')
    else:
        if d == r1+r2 or abs(r1 - r2) == d:
            print('1')
        elif abs(r1-r2) < d < r1+r2:
            print('2')
        else:
            print('0')


# -*- coding: utf-8 -*-
"""
Created on Sun Apr 12 13:18:17 2020

@author: user
"""
import cv2
import numpy

from keras.models import load_model

model = load_model('hand_sign.h5')
CLASS_MAP = {"A": 0,"B": 1,"C": 2,"D": 3,"E": 4,"F": 5,"G": 6,"H": 7,"I": 8,"K": 9,
             "L": 10,"M": 11,"N": 12,"O": 13,"P": 14,"Q": 15,"R": 16,"S": 17,"T": 18,"U": 19,
             "V": 20,"W": 21,"X": 22,"Y": 23,"nothing": 24}

CLASS_MAP_REV = dict(map(reversed, CLASS_MAP.items()))
def mapper(val):
    return CLASS_MAP[val]

def mapper_rev(val):
    return CLASS_MAP_REV[val]

def identify(image):
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = cv2.resize(image, (48, 48))
    image = numpy.expand_dims(image, axis=0)
    image = numpy.array(image)
    pred = model.predict([image])[0]
    key = mapper_rev(numpy.argmax(pred))
    acc = str(int(max(pred)*100))+"%"
    return key,acc

detect = False
letterDetected = "NONE"

# Create a window to display the camera feed
cv2.namedWindow('Camera Output')
cv2.namedWindow('Hand')
# Get pointer to video frames from primary device

WIDTH, HEIGHT = (1000,1000)
FPS = 30
videoFrame = cv2.VideoCapture(0)
videoFrame.set(cv2.CAP_PROP_FRAME_WIDTH,WIDTH);
videoFrame.set(cv2.CAP_PROP_FRAME_HEIGHT,HEIGHT);
videoFrame.set(cv2.CAP_PROP_FPS,FPS);

while True:

    readSucsess, frame = videoFrame.read()
    cv2.rectangle(frame, (150, 50), (400, 300), (255, 255, 255), 2)
    cv2.rectangle(frame, (550, 50), (800, 300), (255, 255, 255), 2)
    sourceImage = frame[50:300, 150:400]
    #handImage = sourceImage.copy()[10:300, 10:300]
    if(detect == True):
        letterDetected, acc = identify(sourceImage)

    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(frame, "Letter: " + letterDetected,
                (150, 350), font, 1.2, (0, 0, 0), 2, cv2.LINE_AA)
    cv2.putText(frame, "Accuracy: " + acc,
                (550, 350), font, 1.2, (0, 0, 0), 2, cv2.LINE_AA)
    cv2.putText(frame, "Place Hand on Left Box",
                (0, 30), font, 1, (255, 255, 255), 2, cv2.LINE_AA)

    cv2.imshow('Camera Output', frame)
    cv2.imshow('Hand', sourceImage)

    keyPressed = cv2.waitKey(30)
    if keyPressed == 27:
        break
    if keyPressed == 32:
        if(detect):
            detect = False
        else:
            detect = True

cv2.destroyWindow('Camera Output')
cv2.destroyWindow('Hand')
videoFrame.release()


#   Faça um programa que tenha uma função chamada "contador()",
#   que receba 3 parâmetros: 'início, fim e passo' e realize a contagem.
#   Seu programa tem que realizar três contagens através da função criada:
#   A) De 1 até 10, de 1 em 1;
#   B) De 10 até 0, de 2 em 2;
#   C) Uma contagem personalizada.

#   FUNÇÕES UTILIZADAS NA ESTÉTICA DO PROGRAMA
cores = {'azul': '\033[1:34m',
         'red': '\033[1:31m',
         'verde':'\033[1:32m',
         'amarelo': '\033[1:33m',
         'negrito': '\033[1m',
         'cls': '\033[m'}
def título(txt):
    print(f'{cores["amarelo"]}-={cores["cls"]}' * 25)
    print(f"{cores['verde']}{txt:^50}{cores['cls']}")
    print(f'{cores["amarelo"]}-={cores["cls"]}' * 25)

#   CABEÇALHO APENAS PARA EFEITOS VISUAIS
título('FUNÇÃO CONTADOR')

#   INÍCIO DO PROGRAMA

from time import sleep
def contador(i, f, p):
    if p == 0:
        p = 1
    elif p < 0:
        p *= -1
    print(f'Contagem de {i} até {f}, de {p} em {p}:')
    if i < f:
        cont = i
        while cont <= f:
            print(f'{cont} ', end='')
            sleep(0.3)
            cont += p
        sleep(0.3)
        print('FIM!')
        sleep(0.3)
        print('-' * 30)
        sleep(0.5)
    else:
        cont = i
        while cont >= f:
            print(f'{cont} ', end='')
            sleep(0.3)
            cont -= p
        sleep(0.3)
        print('FIM!')
        sleep(0.3)
        print('-' * 30)
        sleep(0.5)

contador(1, 10, 1)
contador(10, 0, 2)
print('AGORA É SUA VEZ DE PERSONALIZAR A CONTAGEM!')
ini = int(input('INÍCIO: '))
fim = int(input('FINAL: '))
pas = int(input('PASSO: '))
contador(ini, fim, pas)