1642484940
Como cualquier idioma nuevo, una vez que aprendemos a comunicar algo, queremos practicar. Esto es cierto ya sea que esté aprendiendo francés o aprendiendo a codificar. El problema que tenemos en el formato digital es que encontrar una idea para una aplicación es difícil. Se convierte en un gran esfuerzo programar una aplicación desde cero y generar los datos necesarios. Pero para dominar ese idioma necesitas practicar mucho. Necesita que las palabras se conviertan en una segunda naturaleza y no para hacer referencia a StackOverflow cada dos minutos.
Otro punto de vista, aunque más doloroso, es que hay literalmente millones de aplicaciones en la App Store. Existe una posibilidad muy pequeña de que lo que desea crear sea funcionalmente diferente de lo que ya se ha hecho. Su aplicación no es única. Lo siento, pero allí está. Cosas deprimentes para tan temprano en este artículo, pero quédate conmigo. Hay un lado positivo, y solo podemos ir cuesta arriba desde aquí.
Con ese reconocimiento fuera del camino, hay otra forma de ganarse a los usuarios: la experiencia del usuario.
Es posible que su idea de aplicación no sea completamente única, es posible que tenga un ligero giro en una idea existente que abre nuevas posibilidades, pero en última instancia, los fundamentos siguen siendo los mismos para el usuario.
Pero donde su aplicación diferirá (a menos que desee una infracción grave de derechos de autor) es en la forma en que se ve, la forma en que se siente y la forma en que el usuario interactúa con ella. Esta es toda la experiencia del usuario y ayuda a hacer una aplicación visualmente agradable a la vista, fluida para interactuar, preventiva sobre qué información mostrar al usuario.
Como programador, practicar con diferentes diseños te ayudará a apreciar lo que funciona y lo que no, cómo cambiar el espaciado o los colores realmente puede definir una aplicación. Todas estas son cosas que puede aprender y, lamentablemente, tiene que fallar o caer en trampas antes de comprender qué funciona y comprender los patrones de diseño.
'Entonces, ¿cómo podemos practicar rápidamente en diferentes aplicaciones?', te escucho preguntar. Bueno, a través de las API.
Hay miles de API (interfaz de programación de aplicaciones) gratuitas que existen en Internet que proporcionan una gran cantidad de información.
Esto es excelente porque significa que ya no necesita rascarse la cabeza pensando en una idea para una aplicación de práctica o dedicar tiempo a crear todos los datos que necesita mostrar. Esto ya está hecho para usted y es de fácil acceso.
El concepto es simple:
Tome cualquier API e imagine que una empresa lo contrató para producir una aplicación que muestre estos datos.
Puede jugar con cómo se verá la información, cuántos detalles desea proporcionar o cómo consultar los datos. Puedes jugar con la marca, los colores, las fuentes, el espaciado.
El objetivo final es producir una aplicación que sea agradable para el usuario. La mejor parte de esto es que debe tomar alrededor de 2 a 3 horas por aplicación para crear (al menos una vez que comience a reconocer los patrones de diseño de trabajo), lo que hace que sea realmente fácil practicar sus habilidades y asegurarse de que algunos de los idiomas que está codificando regularmente está realmente grabado.
Estoy usando SwiftUI para estos ejemplos, pero el principio se puede aplicar a cualquier idioma. A continuación, comenzaremos a ver los pasos básicos, seguidos de un ejemplo de trabajo.
Siguiendo los pasos de práctica anteriores, queremos elegir una API. Voy a comenzar con una aplicación de insultos simple, principalmente porque es simple. Como usuario, presiono un botón y muestro un insulto aleatorio en la pantalla. Esta es más una introducción a la funcionalidad de la API, pero nos da algo para ampliar.
Consulte la documentación, que se puede encontrar en el sitio web de la API. Estoy usando una API de insulto :
En el sitio web, normalmente verá un ejemplo del objeto JSON que se devolverá. Esto es lo que tu aplicación necesita traducir.
Para hacer esto, cree una estructura con todos los elementos y tipos de datos esperados declarados, como se indicó anteriormente.
Verá en el futuro que otras API tienen mucha más flexibilidad y pueden proporcionar enlaces a imágenes u otros tipos de datos.
Ahora que nuestra aplicación sabe qué esperar, podemos ver cómo comunicarse con la API:
Task {
let (data, _) = try await URLSession.shared.data(from: URL(string:"https://evilinsult.com/generate_insult.php?lang=en&type=json")!)
let decodedResponse = try? JSONDecoder().decode(InsultModel.self, from: data)
insult = decodedResponse!.insult
}
Este simple bloque de código llamará a la URL y recuperará la respuesta, y luego la decodificará en un objeto de modelo de datos (como se escribió anteriormente).
Podéis ver que https://evilinsult.com/generate_insult.php?lang=en&type=json
es la URL por la que llamamos para recuperar nuestros datos.
Si observa la documentación de la API en línea, verá que al modificar esta URL podemos aplicar filtros adicionales a lo que queremos recuperar. No hay demasiadas opciones para la API de insultos, pero es útil saber esto para proyectos futuros (veremos una demostración de esto a continuación).
A continuación, ¿dónde colocar este código? Podemos colocar esto como la función de un botón, o podemos hacer que este código se ejecute automáticamente siempre que se muestre nuestra vista. Esto es útil para saber si no queremos que nuestra app esté vacía cuando cargue.
Por el bien de este ejemplo, agregaremos el código que se llamará cuando presionemos un botón.
Haciendo referencia a la imagen de arriba, definimos una insult
cadena que contendrá el valor del insulto recuperado.
Cuando presionamos Insult Me!
el botón, esto recuperará el objeto JSON, lo decodificará en un InsultModel
objeto y luego actualizaremos la cadena de insultos con la del InsultModel
objeto insulto.
Si quisiéramos que esto apareciera cuando la aplicación se inicia por primera vez, simplemente colocamos el código dentro Task
de un .onAppear{}
modificador.
Es importante conocer esta ubicación, ya que a menudo la primera vista de una aplicación es una lista de objetos. Poner una llamada a la API en el onAppear
modificador significa que lo primero que hará la aplicación será buscar los objetos para que se puedan cargar en la lista.
A continuación se muestra un ejemplo del uso de esto .onAppear{}
:
Para ampliar esta funcionalidad, es posible que desee mostrar un símbolo o una imagen si el resultado obtenido es una determinada condición, es decir, si una aplicación meteorológica muestra "lluvia", puede mostrar una imagen de lluvia; de lo contrario, si hace sol, una imagen del sol. Para hacer esto, simplemente podemos agregar una declaración de 'cambio'.
Amplíe su aplicación mostrando imágenes
Es posible que desee mostrar una imagen de una API. Para hacer esto, use AsyncImage
y pase una URL a this. Puede probar esto haciendo referencia a la API a continuación para mostrar una foto de perro al azar:
Ejemplo de cervecería
Mi ejemplo final es una base de datos de cervecería simple:
Esta aplicación permitirá al usuario encontrar cervecerías buscando un nombre. Luego recuperará una lista de cervecerías para que el usuario la vea.
Luego, como ejemplo final, mostraremos un ícono diferente según el país en el que se encuentre la cervecería.
El paso 1 es hacer la Brewery
estructura. Necesitamos hacer que esto se ajuste a Identifiable
fin de poner esta información en una lista.
El paso 2 es crear tres propiedades en la parte superior de nuestra vista de contenido. Uno almacenará la matriz completa de valores devueltos. Esta será una Brewery
matriz. La segunda es la palabra de búsqueda que el usuario escribirá. Finalmente, debajo de esto, declaramos la URL de la API (excluyendo la consulta en sí).
Podemos ver que al combinar the apiURL
y the searchTerm
obtenemos la dirección a usar:
@State var breweries:[Brewery] = []
@State var searchTerm:String = ""
var apiURL:String = "https://api.openbrewerydb.org/breweries/search?query="
El paso 3 es crear la lista que mostrará los resultados. Por ahora, todo lo que mostraremos es el nombre de cada Brewery
fila.
List(breweries) { brewery in
Text(brewery.name ?? "")
}
TextField("Search", text: $searchTerm)
.background(.quaternary)
.cornerRadius(8)
.padding(10)
La segunda mitad de este código es TextField
para que el usuario escriba su consulta de búsqueda.
El paso final de la funcionalidad es configurar el botón de búsqueda. La única diferencia aquí con respecto a lo que hemos hecho antes es que para la Cadena de URL, en lugar de indicar la Cadena aquí para usar, simplemente agregamos el apiURL
y el searchTerm
.
También podemos mejorar nuestro código colocando esta llamada en un do catch
cierre y agregando la declaración de impresión (error). Esto nos permite identificar cuándo hay problemas con la decodificación del objeto JSON en nuestros datos.
Esto puede suceder regularmente con diferentes API y, sin información sobre el error, simplemente devolverá un valor nulo. El error dirá por qué falló, como esperar un tipo de datos diferente.
Button("Find Beer!") {
Task{
do{
let (data, _) = try await URLSession.shared.data(from: URL(string:(apiURL + searchTerm))!)
let decodedResponse = try JSONDecoder().decode([Brewery].self, from: data)
breweries = decodedResponse
}catch{
print("error: ", error)
}
}
}
.buttonStyle(.borderedProminent)
.padding(10)
Al juntar todo esto, obtenemos una aplicación funcional que llamará a un término de búsqueda en la base de datos de la cervecería, devolverá los resultados en una matriz y mostrará los resultados como una lista.
Podemos ir un paso más allá para demostrar que se muestra un elemento adicional si se cumple un criterio.
Por ejemplo aquí, mostraré un emoticón si la cervecería está en los Estados Unidos, y un garabato si no está usando SFSymbols
:
func getIcon(country:String) -> String{
switch country {
case "United States": return "smiley"
default: return "scribble"
}
}
Para hacer esto, simplemente pase el nombre del país y, si el caso coincide con un escenario dado, devuelva la cadena del SFSymbol
. Luego, en el List
, para cada uno brewery
indicamos el nombre, y luego podemos mostrar el Image
siguiente. Aquí está el List
código actualizado:
List(breweries) { brewery in
HStack{
Image(systemName: getIcon(country: brewery.country ?? ""))
Text(brewery.name ?? "")
}
}
El resultado final se parece a esto:
Esta es solo una guía para obtener una aplicación funcional rápida con datos. Puede ver en lo anterior que todo esto se hace en menos de 50 líneas de código. Esto tomará de 10 a 15 minutos para llegar a este punto una vez que tenga confianza y haya practicado, lo que significa que luego puede concentrar su tiempo en mirar colores, espacios, tamaños, símbolos e imágenes.
Las aplicaciones que he creado anteriormente aún no son agradables, y el siguiente paso es practicar esto para ver qué funciona y qué no. Con suerte, lo anterior le brinda los conceptos básicos para mostrar elementos basados en un recibo API. Ahora encuentre algunas API y obtenga programación. Algunas de mis aplicaciones rápidas favoritas se pueden crear mediante API gratuitas que hacen lo siguiente:
Ahora que tienes esto. Mi próximo artículo se concentrará en cómo administrar diferentes formatos y crear temas. Centralizar gran parte de esta información ayudará a crear y modificar vistas desde un solo lugar. Codificación feliz.
1641693600
Si es un desarrollador de Python que está pensando en comenzar con el desarrollo móvil, entonces el marco Kivy es su mejor opción. Con Kivy, puede desarrollar aplicaciones independientes de la plataforma que compilan para iOS, Android, Windows, macOS y Linux. En este artículo, cubriremos Android específicamente porque es el más utilizado.
Construiremos una aplicación generadora de números aleatorios simple que puede instalar en su teléfono y probar cuando haya terminado. Para continuar con este artículo, debe estar familiarizado con Python. ¡Empecemos!
Primero, necesitará un nuevo directorio para su aplicación. Asegúrese de tener Python instalado en su máquina y abra un nuevo archivo de Python. Deberá instalar el módulo Kivy desde su terminal usando cualquiera de los comandos a continuación. Para evitar conflictos de paquetes, asegúrese de instalar Kivy en un entorno virtual:
pip install kivy
//
pip3 install kivy
Una vez que haya instalado Kivy, debería ver un mensaje de éxito de su terminal que se parece a las capturas de pantalla a continuación:
Instalación decepcionada
Instalación exitosa de Kivy
A continuación, navegue a la carpeta de su proyecto. En el main.py
archivo, necesitaremos importar el módulo Kivy y especificar qué versión queremos. Puede usar Kivy v2.0.0, pero si tiene un teléfono inteligente anterior a Android 8.0, le recomiendo usar Kivy v1.9.0. Puede jugar con las diferentes versiones durante la compilación para ver las diferencias en las características y el rendimiento.
Agregue el número de versión justo después de la import kivy
línea de la siguiente manera:
kivy.require('1.9.0')
Ahora, crearemos una clase que básicamente definirá nuestra aplicación; Voy a nombrar el mío RandomNumber
. Esta clase heredará la app
clase de Kivy. Por lo tanto, debe importar app
agregando from kivy.app import App
:
class RandomNumber(App):
En la RandomNumber
clase, deberá agregar una función llamada build
, que toma un self
parámetro. Para devolver la interfaz de usuario, usaremos la build
función. Por ahora, lo tengo devuelto como una simple etiqueta. Para hacerlo, deberá importar Label
usando la línea from kivy.uix.label import Label
:
import kivy
from kivy.app import App
from kivy.uix.label import Label
class RandomNumber(App):
def build(self):
return Label(text="Random Number Generator")
¡Ahora, el esqueleto de nuestra aplicación está completo! Antes de continuar, debe crear una instancia de la RandomNumber
clase y ejecutarla en su terminal o IDE para ver la interfaz:
importar kivy de kivy.app importar aplicación de kivy.uix.label clase de etiqueta de importación RandomNumber(App): def build(self): return Label(text="Generador de números aleatorios") randomApp = RandomNumber() randomApp.run()
Cuando ejecuta la instancia de clase con el texto Random Number Generator
, debería ver una interfaz o ventana simple que se parece a la siguiente captura de pantalla:
Interfaz simple después de ejecutar el código.
No podrá ejecutar el texto en Android hasta que haya terminado de construir todo.
A continuación, necesitaremos una forma de subcontratar la interfaz. Primero, crearemos un archivo Kivy en nuestro directorio que albergará la mayor parte de nuestro trabajo de diseño. Querrá nombrar este archivo con el mismo nombre que su clase usando letras minúsculas y una .kv
extensión. Kivy asociará automáticamente el nombre de la clase y el nombre del archivo, pero es posible que no funcione en Android si son exactamente iguales.
Dentro de ese .kv
archivo, debe especificar el diseño de su aplicación, incluidos elementos como la etiqueta, los botones, los formularios, etc. Para simplificar esta demostración, agregaré una etiqueta para el título Random Number
, una etiqueta que servirá como marcador de posición. para el número aleatorio que se genera _
, y un Generate
botón que llama a la generate
función.
Mi .kv
archivo se parece al siguiente código, pero puede jugar con los diferentes valores para que se ajusten a sus requisitos:
<boxLayout>:
orientation: "vertical"
Label:
text: "Random Number"
font_size: 30
color: 0, 0.62, 0.96
Label:
text: "_"
font_size: 30
Button:
text: "Generate"
font_size: 15
En el main.py
archivo, ya no necesita la Label
declaración de importación porque el archivo Kivy se encarga de su interfaz de usuario. Sin embargo, necesita importar boxlayout
, que utilizará en el archivo Kivy.
En su archivo principal, debe agregar la declaración de importación y editar su main.py
archivo para leer return BoxLayout()
el build
método:
from kivy.uix.boxlayout import BoxLayout
Si ejecuta el comando anterior, debería ver una interfaz simple que tiene el título del número aleatorio, el _
marcador de posición y el generate
botón en el que se puede hacer clic:
Aplicación de números aleatorios renderizada
Tenga en cuenta que no tuvo que importar nada para que funcione el archivo Kivy. Básicamente, cuando ejecuta la aplicación, regresa boxlayout
buscando un archivo dentro del archivo Kivy con el mismo nombre que su clase. Tenga en cuenta que esta es una interfaz simple y puede hacer que su aplicación sea tan robusta como desee. Asegúrese de consultar la documentación del idioma Kv .
Ahora que nuestra aplicación está casi terminada, necesitaremos una función simple para generar números aleatorios cuando un usuario haga clic en el generate
botón y luego mostrar ese número aleatorio en la interfaz de la aplicación. Para hacerlo, necesitaremos cambiar algunas cosas en nuestros archivos.
Primero, importaremos el módulo que usaremos para generar un número aleatorio con import random
. Luego, crearemos una función o método que llame al número generado. Para esta demostración, usaré un rango entre 0
y 2000
. Generar el número aleatorio es simple con el random.randint(0, 2000)
comando. Agregaremos esto a nuestro código en un momento.
A continuación, crearemos otra clase que será nuestra propia versión del box layout
. Nuestra clase tendrá que heredar la box layout
clase, que alberga el método para generar números aleatorios y representarlos en la interfaz:
class MyRoot(BoxLayout):
def __init__(self):
super(MyRoot, self).__init__()
Dentro de esa clase, crearemos el generate
método, que no solo generará números aleatorios, sino que también manipulará la etiqueta que controla lo que se muestra como número aleatorio en el archivo Kivy.
Para acomodar este método, primero necesitaremos hacer cambios en el .kv
archivo. Dado que la MyRoot
clase ha heredado el box layout
, puede crear MyRoot
el elemento de nivel superior en su .kv
archivo:
<MyRoot>:
BoxLayout:
orientation: "vertical"
Label:
text: "Random Number"
font_size: 30
color: 0, 0.62, 0.96
Label:
text: "_"
font_size: 30
Button:
text: "Generate"
font_size: 15
Tenga en cuenta que todavía mantiene todas las especificaciones de la interfaz de usuario con sangría en el archivo Box Layout
. Después de esto, debe agregar una identificación a la etiqueta que contendrá los números generados, lo que facilita la manipulación cuando generate
se llama a la función. Debe especificar la relación entre la ID en este archivo y otra en el código principal en la parte superior, justo antes de la BoxLayout
línea:
<MyRoot>:
random_label: random_label
BoxLayout:
orientation: "vertical"
Label:
text: "Random Number"
font_size: 30
color: 0, 0.62, 0.96
Label:
id: random_label
text: "_"
font_size: 30
Button:
text: "Generate"
font_size: 15
La random_label: random_label
línea básicamente significa que la etiqueta con el ID random_label
se asignará a random_label
en el main.py
archivo, lo que significa que cualquier acción que manipula random_label
serán mapeados en la etiqueta con el nombre especificado.
Ahora podemos crear el método para generar el número aleatorio en el archivo principal:
def generate_number(self):
self.random_label.text = str(random.randint(0, 2000))
# notice how the class method manipulates the text attributre of the random label by a# ssigning it a new random number generate by the 'random.randint(0, 2000)' funcion. S# ince this the random number generated is an integer, typecasting is required to make # it a string otherwise you will get a typeError in your terminal when you run it.
La MyRoot
clase debería parecerse al siguiente código:
class MyRoot(BoxLayout):
def __init__(self):
super(MyRoot, self).__init__()
def generate_number(self):
self.random_label.text = str(random.randint(0, 2000))
¡Felicidades! Ya ha terminado con el archivo principal de la aplicación. Lo único que queda por hacer es asegurarse de llamar a esta función cuando se haga generate
clic en el botón. Solo necesita agregar la línea on_press: root.generate_number()
a la parte de selección de botones de su .kv
archivo:
<MyRoot>:
random_label: random_label
BoxLayout:
orientation: "vertical"
Label:
text: "Random Number"
font_size: 30
color: 0, 0.62, 0.96
Label:
id: random_label
text: "_"
font_size: 30
Button:
text: "Generate"
font_size: 15
on_press: root.generate_number()
Ahora, puede ejecutar la aplicación.
Antes de compilar nuestra aplicación en Android, tengo malas noticias para los usuarios de Windows. Necesitará Linux o macOS para compilar su aplicación de Android. Sin embargo, no necesita tener una distribución de Linux separada, en su lugar, puede usar una máquina virtual.
Para compilar y generar una .apk
aplicación Android completa , usaremos una herramienta llamada Buildozer . Instalemos Buildozer a través de nuestra terminal usando uno de los siguientes comandos:
pip3 install buildozer
//
pip install buildozer
Ahora, instalaremos algunas de las dependencias requeridas de Buildozer. Estoy en Linux Ergo, así que usaré comandos específicos de Linux. Debe ejecutar estos comandos uno por uno:
sudo apt update
sudo apt install -y git zip unzip openjdk-13-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev
pip3 install --upgrade Cython==0.29.19 virtualenv
# add the following line at the end of your ~/.bashrc file
export PATH=$PATH:~/.local/bin/
Después de ejecutar los comandos específicos, ejecute buildozer init
. Debería ver un resultado similar a la captura de pantalla a continuación:
Inicialización exitosa de Buildozer
El comando anterior crea un .spec
archivo Buildozer , que puede usar para hacer especificaciones para su aplicación, incluido el nombre de la aplicación, el ícono, etc. El .spec
archivo debe verse como el bloque de código a continuación:
[app]
# (str) Title of your application
title = My Application
# (str) Package name
package.name = myapp
# (str) Package domain (needed for android/ios packaging)
package.domain = org.test
# (str) Source code where the main.py live
source.dir = .
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas
# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png
# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec
# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin
# (list) List of exclusions using pattern matching
#source.exclude_patterns = license,images/*/*.jpg
# (str) Application versioning (method 1)
version = 0.1
# (str) Application versioning (method 2)
# version.regex = __version__ = \['"\](.*)['"]
# version.filename = %(source.dir)s/main.py
# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy
# (list) Garden requirements
#garden_requirements =
# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png
# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png
# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait
# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
#
# OSX Specific
#
#
# author = © Copyright Info
# change the major version of python used by the app
osx.python_version = 3
# Kivy version to use
osx.kivy_version = 1.9.1
#
# Android specific
#
# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0
# (string) Presplash background color (for new android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF
# (list) Permissions
#android.permissions = INTERNET
# (int) Target Android API, should be as high as possible.
#android.api = 27
# (int) Minimum API your APK will support.
#android.minapi = 21
# (int) Android SDK version to use
#android.sdk = 20
# (str) Android NDK version to use
#android.ndk = 19b
# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
#android.ndk_api = 21
# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
#android.ndk_path =
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =
# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =
# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# android.skip_update = False
# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
# android.accept_sdk_license = False
# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity
# (str) Android app theme, default is ok for Kivy-based app
# android.apptheme = "@android:style/Theme.NoTitleBar"
# (list) Pattern to whitelist for the whole project
#android.whitelist =
# (str) Path to a custom whitelist file
#android.whitelist_src =
# (str) Path to a custom blacklist file
#android.blacklist_src =
# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =
# (list) Android AAR archives to add (currently works only with sdl2_gradle
# bootstrap)
#android.add_aars =
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
# bootstrap)
#android.gradle_dependencies =
# (list) add java compile options
# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
# see https://developer.android.com/studio/write/java8-support for further information
# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"
# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
# please enclose in double quotes
# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
#android.add_gradle_repositories =
# (list) packaging options to add
# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
# can be necessary to solve conflicts in gradle_dependencies
# please enclose in double quotes
# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
#android.add_gradle_repositories =
# (list) Java classes to add as activities to the manifest.
#android.add_activities = com.example.ExampleActivity
# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME
# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =
# (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard
# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_arm64_v8a = libs/android-v8/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so
# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False
# (list) Android application meta-data to set (key=value format)
#android.meta_data =
# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =
# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
#android.uses_library =
# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D
# (bool) Copy library instead of making a libpymodules.so
#android.copy_libs = 1
# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.arch = armeabi-v7a
# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1
#
# Python for android (p4a) specific
#
# (str) python-for-android fork to use, defaults to upstream (kivy)
#p4a.fork = kivy
# (str) python-for-android branch to use, defaults to master
#p4a.branch = master
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#p4a.source_dir =
# (str) The directory in which python-for-android should look for your own build recipes (if any)
#p4a.local_recipes =
# (str) Filename to the hook for p4a
#p4a.hook =
# (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2
# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =
#
# iOS specific
#
# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master
# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0
# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s
[buildozer]
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2
# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1
# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer
# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin
# -----------------------------------------------------------------------------
# List as sections
#
# You can define all the "list" as [section:key].
# Each line will be considered as a option to the list.
# Let's take [app] / source.exclude_patterns.
# Instead of doing:
#
#[app]
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
# This can be translated into:
#
#[app:source.exclude_patterns]
#license
#data/audio/*.wav
#data/images/original/*
#
# -----------------------------------------------------------------------------
# Profiles
#
# You can extend section / key with a profile
# For example, you want to deploy a demo version of your application without
# HD content. You could first change the title to add "(demo)" in the name
# and extend the excluded directories to remove the HD content.
#
#[app@demo]
#title = My Application (demo)
#
#[app:source.exclude_patterns@demo]
#images/hd/*
#
# Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug
Si desea especificar cosas como el ícono, los requisitos, la pantalla de carga, etc., debe editar este archivo. Después de realizar todas las ediciones deseadas en su aplicación, ejecute buildozer -v android debug
desde el directorio de su aplicación para construir y compilar su aplicación. Esto puede llevar un tiempo, especialmente si tiene una máquina lenta.
Una vez finalizado el proceso, su terminal debería tener algunos registros, uno que confirme que la compilación fue exitosa:
Construcción exitosa de Android
También debe tener una versión APK de su aplicación en su directorio bin. Este es el ejecutable de la aplicación que instalará y ejecutará en su teléfono:
Android .apk en el directorio bin
¡Felicidades! Si ha seguido este tutorial paso a paso, debería tener una aplicación simple de generador de números aleatorios en su teléfono. Juega con él y ajusta algunos valores, luego reconstruye. Ejecutar la reconstrucción no llevará tanto tiempo como la primera compilación.
Como puede ver, crear una aplicación móvil con Python es bastante sencillo , siempre que esté familiarizado con el marco o módulo con el que está trabajando. Independientemente, la lógica se ejecuta de la misma manera.
Familiarícese con el módulo Kivy y sus widgets. Nunca se puede saber todo a la vez. Solo necesita encontrar un proyecto y mojarse los pies lo antes posible. Codificación feliz.
Enlace: https://blog.logrocket.com/build-android-application-kivy-python-framework/
1677864120
This package contains a variety of functions from the field robust statistical methods. Many are estimators of location or dispersion; others estimate the standard error or the confidence intervals for the location or dispresion estimators, generally computed by the bootstrap method.
Many functions in this package are based on the R package WRS (an R-Forge repository) by Rand Wilcox. Others were contributed by users as needed. References to the statistics literature can be found below.
This package requires Compat
, Rmath
, Dataframes
, and Distributions
. They can be installed automatically, or by invoking Pkg.add("packagename")
.
tmean(x, tr=0.2)
- Trimmed mean: mean of data with the lowest and highest fraction tr
of values omitted.winmean(x, tr=0.2)
- Winsorized mean: mean of data with the lowest and highest fraction tr
of values squashed to the 20%ile or 80%ile value, respectively.tauloc(x)
- Tau measure of location by Yohai and Zamar.onestep(x)
- One-step M-estimator of location using Huber's ψmom(x)
- Modified one-step M-estimator of location (MOM)bisquareWM(x)
- Mean with weights given by the bisquare rho function.huberWM(x)
- Mean with weights given by Huber's rho function.trimean(x)
- Tukey's trimean, the average of the median and the midhinge.winvar(x, tr=0.2)
- Winsorized variance.wincov(x, y, tr=0.2)
- Winsorized covariance.pbvar(x)
- Percentage bend midvariance.bivar(x)
- Biweight midvariance.tauvar(x)
- Tau measure of scale by Yohai and Zamar.iqrn(x)
- Normalized inter-quartile range (normalized to equal σ for Gaussians).shorthrange(x)
- Length of the shortest closed interval containing at least half the data.scaleQ(x)
- Normalized Rousseeuw & Croux Q statistic, from the 25%ile of all 2-point distances.scaleS(x)
- Normalized Rousseeuw & Croux S statistic, from the median of the median of all 2-point distances.shorthrange!(x)
, scaleQ!(x)
, and scaleS!(x)
are non-copying (that is, x
-modifying) forms of the above.trimse(x)
- Standard error of the trimmed mean.trimci(x)
- Confidence interval for the trimmed mean.msmedse(x)
- Standard error of the median.binomci(s,n)
- Binomial confidence interval (Pratt's method).acbinomci(s,n)
- Binomial confidence interval (Agresti-Coull method).sint(x)
- Confidence interval for the median (with optional p-value).momci(x)
- Confidence interval of the modified one-step M-estimator of location (MOM).trimpb(x)
- Confidence interval for trimmed mean.pcorb(x)
- Confidence intervale for Pearson's correlation coefficient.yuend
- Compare the trimmed means of two dependent random variables.bootstrapci(x, est=f)
- Compute a confidence interval for estimator f(x)
by bootstrap methods.bootstrapse(x, est=f)
- Compute a standard error of estimator f(x)
by bootstrap methods.winval(x, tr=0.2)
- Return a Winsorized copy of the data.idealf(x)
- Ideal fourths, interpolated 1st and 3rd quartiles.outbox(x)
- Outlier detection.hpsi(x)
- Huber's ψ function.contam_randn
- Contaminated normal distribution (generates random deviates)._weightedhighmedian(x)
- Weighted median (breaks ties by rounding up). Used in scaleQ.For location, consider the bisquareWM
with k=3.9σ, if you can make any reasonable guess as to the "Gaussian-like width" σ (see dispersion estimators for this). If not, trimean
is a good second choice, though less efficient. Also, though the author personally has no experience with them, tauloc
, onestep
, and mom
might be useful.
For dispersion, the scaleS
is a good general choice, though scaleQ
is very efficient for nearly Gaussian data. The MAD is the most robust though less efficient. If scaleS doesn't work, then shorthrange is a good second choice.
The first reference on scaleQ and scaleS (below) is a lengthy discussion of the tradeoffs among scaleQ, scaleS, shortest half, and median absolute deviation (MAD, see BaseStats.mad for Julia implementation). All four have the virtue of having the maximum possible breakdown point, 50%. This means that replacing up to 50% of the data with unbounded bad values leaves the statistic still bounded. The efficiency of Q is better than S and S is better than MAD (for Gaussian distributions), and the influence of a single bad point and the bias due to a fraction of bad points is only slightly larger on Q or S than on MAD. Unlike MAD, the other three do not implicitly assume a symmetric distribution.
To choose between Q and S, the authors note that Q has higher statistical efficiency, but S is typically twice as fast to compute and has lower gross-error sensitivity. An interesting advantage of Q over the others is that its influence function is continuous. For a rough idea about the efficiency, the large-N limit of the standardized variance of each quantity is 2.722 for MAD, 1.714 for S, and 1.216 for Q, relative to 1.000 for the standard deviation (given Gaussian data). The paper gives the ratios for Cauchy and exponential distributions, too; the efficiency advantages of Q are less for Cauchy than for the other distributions.
#Set up a sample dataset:
x=[1.672064, 0.7876588, 0.317322, 0.9721646, 0.4004206, 1.665123, 3.059971, 0.09459603, 1.27424, 3.522148,
0.8211308, 1.328767, 2.825956, 0.1102891, 0.06314285, 2.59152, 8.624108, 0.6516885, 5.770285, 0.5154299]
julia> mean(x) #the mean of this dataset
1.853401259
tmean
: trimmed meanjulia> tmean(x) #20% trimming by default
1.2921802666666669
julia> tmean(x, tr=0) #no trimming; the same as the output of mean()
1.853401259
julia> tmean(x, tr=0.3) #30% trimming
1.1466045875000002
julia> tmean(x, tr=0.5) #50% trimming, which gives you the median of the dataset.
1.1232023
winval
: winsorize dataThat is, return a copy of the input array, with the extreme low or high values replaced by the lowest or highest non-extreme value, repectively. The fraction considered extreme can be between 0 and 0.5, with 0.2 as the default.
julia> winval(x) #20% winsorization; can be changed via the named argument `tr`.
20-element Any Array:
1.67206
0.787659
0.400421
0.972165
...
0.651689
2.82596
0.51543
winmean
, winvar
, wincov
: winsorized mean, variance, and covariancejulia> winmean(x) #20% winsorization; can be changed via the named argument `tr`.
1.4205834800000001
julia> winvar(x)
0.998659015947531
julia> wincov(x, x)
0.998659015947531
julia> wincov(x, x.^2)
3.2819238397424004
trimse
: estimated standard error of the trimmed meanjulia> trimse(x) #20% winsorization; can be changed via the named argument `tr`.
0.3724280347984342
trimci
: (1-α) confidence interval for the trimmed meanCan be used for paired groups if x
consists of the difference scores of two paired groups.
julia> trimci(x) #20% winsorization; can be changed via the named argument `tr`.
(1-α) confidence interval for the trimmed mean
Degrees of freedom: 11
Estimate: 1.292180
Statistic: 3.469611
Confidence interval: 0.472472 2.111889
p value: 0.005244
idealf
: the ideal fourths:Returns (q1,q3)
, the 1st and 3rd quartiles. These will be a weighted sum of the values that bracket the exact quartiles, analogous to how we handle the median of an even-length array.
julia> idealf(x)
(0.4483411416666667,2.7282743333333332)
pbvar
: percentage bend midvarianceA robust estimator of scale (dispersion). See NIST ITL webpage for more.
julia> pbvar(x)
2.0009575278957623
bivar
: biweight midvarianceA robust estimator of scale (dispersion). See NIST ITL webpage for more.
julia> bivar(x)
1.5885279811329132
tauloc
, tauvar
: tau measure of location and scaleRobust estimators of location and scale, with breakdown points of 50%.
See Yohai and Zamar JASA, vol 83 (1988), pp 406-413 and Maronna and Zamar Technometrics, vol 44 (2002), pp. 307-317.
julia> tauloc(x) #the named argument `cval` is 4.5 by default.
1.2696652567510853
julia> tauvar(x)
1.53008203090696
outbox
: outlier detectionUse a modified boxplot rule based on the ideal fourths; when the named argument mbox
is set to true
, a modification of the boxplot rule suggested by Carling (2000) is used.
julia> outbox(x)
Outlier detection method using
the ideal-fourths based boxplot rule
Outlier ID: 17
Outlier value: 8.62411
Number of outliers: 1
Non-outlier ID: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20
msmedse
: Standard error of the medianReturn the standard error of the median, computed through the method recommended by McKean and Schrader (1984).
julia> msmedse(x)
0.4708261134886094
binomci()
, acbinomci()
: Binomial confidence intervalCompute the (1-α) confidence interval for p, the binomial probability of success, given s
successes in n
trials. Instead of s
and n
, can use a vector x
whose values are all 0 and 1, recording failure/success one trial at a time. Returns an object.
binomci
uses Pratt's method; acbinomci
uses a generalization of the Agresti-Coull method that was studied by Brown, Cai, & DasGupta.
julia> binomci(2, 10) # # of success and # of total trials are provided. By default alpha=.05
p_hat: 0.2000
confidence interval: 0.0274 0.5562
Sample size 10
julia> trials=[1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0]
julia> binomci(trials, alpha=0.01) #trial results are provided in array form consisting of 1's and 0's.
p_hat: 0.5000
confidence interval: 0.1768 0.8495
Sample size 12
julia> acbinomci(2, 10) # # of success and # of total trials are provided. By default alpha=.05
p_hat: 0.2000
confidence interval: 0.0459 0.5206
Sample size 10
sint()
Compute the confidence interval for the median. Optionally, uses the Hettmansperger-Sheather interpolation method to also estimate a p-value.
julia> sint(x)
Confidence interval for the median
Confidence interval: 0.547483 2.375232
julia> sint(x, 0.6)
Confidence interval for the median with p-val
Confidence interval: 0.547483 2.375232
p value: 0.071861
hpsi
Compute Huber's ψ. The default bending constant is 1.28.
julia> hpsi(x)
20-element Array{Float64,1}:
1.28
0.787659
0.317322
0.972165
0.400421
...
onestep
Compute one-step M-estimator of location using Huber's ψ. The default bending constant is 1.28.
julia> onestep(x)
1.3058109021286803
bootstrapci
, bootstrapse
Compute a bootstrap, (1-α) confidence interval (bootstrapci
) or a standard error (bootstrapse
) for the measure of location corresponding to the argument est
. By default, the median is used. Default α=0.05.
julia> ci = bootstrapci(x, est=onestep, nullvalue=0.6)
Estimate: 1.305811
Confidence interval: 0.687723 2.259071
p value: 0.026000
julia> se = bootstrapse(x, est=onestep)
0.41956761772722817
mom
and mom!
Returns a modified one-step M-estimator of location (MOM), which is the unweighted mean of all values not more than (bend times the mad(x)
) away from the data median.
julia> mom(x)
1.2596462322222222
momci
Compute the bootstrap (1-α) confidence interval for the MOM-estimator of location based on Huber's ψ. Default α=0.05.
julia> momci(x, seed=2, nboot=2000, nullvalue=0.6)
Estimate: 1.259646
Confidence interval: 0.504223 2.120979
p value: 0.131000
contam_randn
Create contaminated normal distributions. Most values will by from a N(0,1) zero-mean unit-variance normal distribution. A fraction epsilon
of all values will have k
times the standard devation of the others. Default: epsilon=0.1
and k=10
.
julia> srand(1);
julia> std(contam_randn(2000))
3.516722458797104
trimpb
Compute a (1-α) confidence interval for a trimmed mean by bootstrap methods.
julia> trimpb(x, nullvalue=0.75)
Estimate: 1.292180
Confidence interval: 0.690539 2.196381
p value: 0.086000
pcorb
Compute a .95 confidence interval for Pearson's correlation coefficient. This function uses an adjusted percentile bootstrap method that gives good results when the error term is heteroscedastic.
julia> pcorb(x, x.^5)
Estimate: 0.802639
Confidence interval: 0.683700 0.963478
yuend
Compare the trimmed means of two dependent random variables using the data in x and y. The default amount of trimming is 20%.
julia> srand(3)
julia> y2 = randn(20)+3;
julia> yuend(x, y2)
Comparing the trimmed means of two dependent variables.
Sample size: 20
Degrees of freedom: 11
Estimate: -1.547776
Standard error: 0.460304
Statistic: -3.362507
Confidence interval: -2.560898 -0.534653
p value: 0.006336
See UNMAINTAINED.md
for information about functions that the maintainers have not yet understood but also not yet deleted entirely.
Percentage bend and related estimators come from L.H. Shoemaker and T.P. Hettmansperger "Robust estimates and tests for the one- and two-sample scale models" in Biometrika Vol 69 (1982) pp. 47-53.
Tau measures of location and scale are from V.J. Yohai and R.H. Zamar "High Breakdown-Point Estimates of Regression by Means of the Minimization of an Efficient Scale" in J. American Statistical Assoc. vol 83 (1988) pp. 406-413.
The outbox(..., mbox=true)
modification was suggested in K. Carling, "Resistant outlier rules and the non-Gaussian case" in Computational Statistics and Data Analysis vol 33 (2000), pp. 249-258. doi:10.1016/S0167-9473(99)00057-2
The estimate of the standard error of the median, msmedse(x)
, is computed by the method of J.W. McKean and R.M. Schrader, "A comparison of methods for studentizing the sample median" in Communications in Statistics: Simulation and Computation vol 13 (1984) pp. 751-773. doi:10.1080/03610918408812413
For Pratt's method of computing binomial confidence intervals, see J.W. Pratt (1968) "A normal approximation for binomial, F, Beta, and other common, related tail probabilities, II" J. American Statistical Assoc., vol 63, pp. 1457- 1483, doi:10.1080/01621459.1968.10480939. Also R.G. Newcombe "Confidence Intervals for a binomial proportion" Stat. in Medicine vol 13 (1994) pp 1283-1285, doi:10.1002/sim.4780131209.
For the Agresti-Coull method of computing binomial confidence intervals, see L.D. Brown, T.T. Cai, & A. DasGupta "Confidence Intervals for a Binomial Proportion and Asymptotic Expansions" in Annals of Statistics, vol 30 (2002), pp. 160-201.
Shortest Half-range comes from P.J. Rousseeuw and A.M. Leroy, "A Robust Scale Estimator Based on the Shortest Half" in Statistica Neerlandica Vol 42 (1988), pp. 103-116. doi:10.1111/j.1467-9574.1988.tb01224.x . See also R.D. Martin and R. H. Zamar, "Bias-Robust Estimation of Scale" in Annals of Statistics Vol 21 (1993) pp. 991-1017. doi:10.1214/aoe/1176349161
Scale-Q and Scale-S statistics are described in P.J. Rousseeuw and C. Croux "Alternatives to the Median Absolute Deviation" in J. American Statistical Assoc. Vo 88 (1993) pp 1273-1283. The time-efficient algorithms for computing them appear in C. Croux and P.J. Rousseeuw, "Time-Efficient Algorithms for Two Highly Robust Estimators of Scale" in Computational Statistics, Vol I (1992), Y. Dodge and J. Whittaker editors, Heidelberg, Physica-Verlag, pp 411-428. If link fails, see ftp://ftp.win.ua.ac.be/pub/preprints/92/Timeff92.pdf
Author: Mrxiaohe
Source Code: https://github.com/mrxiaohe/RobustStats.jl
License: MIT license
1642484940
Como cualquier idioma nuevo, una vez que aprendemos a comunicar algo, queremos practicar. Esto es cierto ya sea que esté aprendiendo francés o aprendiendo a codificar. El problema que tenemos en el formato digital es que encontrar una idea para una aplicación es difícil. Se convierte en un gran esfuerzo programar una aplicación desde cero y generar los datos necesarios. Pero para dominar ese idioma necesitas practicar mucho. Necesita que las palabras se conviertan en una segunda naturaleza y no para hacer referencia a StackOverflow cada dos minutos.
Otro punto de vista, aunque más doloroso, es que hay literalmente millones de aplicaciones en la App Store. Existe una posibilidad muy pequeña de que lo que desea crear sea funcionalmente diferente de lo que ya se ha hecho. Su aplicación no es única. Lo siento, pero allí está. Cosas deprimentes para tan temprano en este artículo, pero quédate conmigo. Hay un lado positivo, y solo podemos ir cuesta arriba desde aquí.
Con ese reconocimiento fuera del camino, hay otra forma de ganarse a los usuarios: la experiencia del usuario.
Es posible que su idea de aplicación no sea completamente única, es posible que tenga un ligero giro en una idea existente que abre nuevas posibilidades, pero en última instancia, los fundamentos siguen siendo los mismos para el usuario.
Pero donde su aplicación diferirá (a menos que desee una infracción grave de derechos de autor) es en la forma en que se ve, la forma en que se siente y la forma en que el usuario interactúa con ella. Esta es toda la experiencia del usuario y ayuda a hacer una aplicación visualmente agradable a la vista, fluida para interactuar, preventiva sobre qué información mostrar al usuario.
Como programador, practicar con diferentes diseños te ayudará a apreciar lo que funciona y lo que no, cómo cambiar el espaciado o los colores realmente puede definir una aplicación. Todas estas son cosas que puede aprender y, lamentablemente, tiene que fallar o caer en trampas antes de comprender qué funciona y comprender los patrones de diseño.
'Entonces, ¿cómo podemos practicar rápidamente en diferentes aplicaciones?', te escucho preguntar. Bueno, a través de las API.
Hay miles de API (interfaz de programación de aplicaciones) gratuitas que existen en Internet que proporcionan una gran cantidad de información.
Esto es excelente porque significa que ya no necesita rascarse la cabeza pensando en una idea para una aplicación de práctica o dedicar tiempo a crear todos los datos que necesita mostrar. Esto ya está hecho para usted y es de fácil acceso.
El concepto es simple:
Tome cualquier API e imagine que una empresa lo contrató para producir una aplicación que muestre estos datos.
Puede jugar con cómo se verá la información, cuántos detalles desea proporcionar o cómo consultar los datos. Puedes jugar con la marca, los colores, las fuentes, el espaciado.
El objetivo final es producir una aplicación que sea agradable para el usuario. La mejor parte de esto es que debe tomar alrededor de 2 a 3 horas por aplicación para crear (al menos una vez que comience a reconocer los patrones de diseño de trabajo), lo que hace que sea realmente fácil practicar sus habilidades y asegurarse de que algunos de los idiomas que está codificando regularmente está realmente grabado.
Estoy usando SwiftUI para estos ejemplos, pero el principio se puede aplicar a cualquier idioma. A continuación, comenzaremos a ver los pasos básicos, seguidos de un ejemplo de trabajo.
Siguiendo los pasos de práctica anteriores, queremos elegir una API. Voy a comenzar con una aplicación de insultos simple, principalmente porque es simple. Como usuario, presiono un botón y muestro un insulto aleatorio en la pantalla. Esta es más una introducción a la funcionalidad de la API, pero nos da algo para ampliar.
Consulte la documentación, que se puede encontrar en el sitio web de la API. Estoy usando una API de insulto :
En el sitio web, normalmente verá un ejemplo del objeto JSON que se devolverá. Esto es lo que tu aplicación necesita traducir.
Para hacer esto, cree una estructura con todos los elementos y tipos de datos esperados declarados, como se indicó anteriormente.
Verá en el futuro que otras API tienen mucha más flexibilidad y pueden proporcionar enlaces a imágenes u otros tipos de datos.
Ahora que nuestra aplicación sabe qué esperar, podemos ver cómo comunicarse con la API:
Task {
let (data, _) = try await URLSession.shared.data(from: URL(string:"https://evilinsult.com/generate_insult.php?lang=en&type=json")!)
let decodedResponse = try? JSONDecoder().decode(InsultModel.self, from: data)
insult = decodedResponse!.insult
}
Este simple bloque de código llamará a la URL y recuperará la respuesta, y luego la decodificará en un objeto de modelo de datos (como se escribió anteriormente).
Podéis ver que https://evilinsult.com/generate_insult.php?lang=en&type=json
es la URL por la que llamamos para recuperar nuestros datos.
Si observa la documentación de la API en línea, verá que al modificar esta URL podemos aplicar filtros adicionales a lo que queremos recuperar. No hay demasiadas opciones para la API de insultos, pero es útil saber esto para proyectos futuros (veremos una demostración de esto a continuación).
A continuación, ¿dónde colocar este código? Podemos colocar esto como la función de un botón, o podemos hacer que este código se ejecute automáticamente siempre que se muestre nuestra vista. Esto es útil para saber si no queremos que nuestra app esté vacía cuando cargue.
Por el bien de este ejemplo, agregaremos el código que se llamará cuando presionemos un botón.
Haciendo referencia a la imagen de arriba, definimos una insult
cadena que contendrá el valor del insulto recuperado.
Cuando presionamos Insult Me!
el botón, esto recuperará el objeto JSON, lo decodificará en un InsultModel
objeto y luego actualizaremos la cadena de insultos con la del InsultModel
objeto insulto.
Si quisiéramos que esto apareciera cuando la aplicación se inicia por primera vez, simplemente colocamos el código dentro Task
de un .onAppear{}
modificador.
Es importante conocer esta ubicación, ya que a menudo la primera vista de una aplicación es una lista de objetos. Poner una llamada a la API en el onAppear
modificador significa que lo primero que hará la aplicación será buscar los objetos para que se puedan cargar en la lista.
A continuación se muestra un ejemplo del uso de esto .onAppear{}
:
Para ampliar esta funcionalidad, es posible que desee mostrar un símbolo o una imagen si el resultado obtenido es una determinada condición, es decir, si una aplicación meteorológica muestra "lluvia", puede mostrar una imagen de lluvia; de lo contrario, si hace sol, una imagen del sol. Para hacer esto, simplemente podemos agregar una declaración de 'cambio'.
Amplíe su aplicación mostrando imágenes
Es posible que desee mostrar una imagen de una API. Para hacer esto, use AsyncImage
y pase una URL a this. Puede probar esto haciendo referencia a la API a continuación para mostrar una foto de perro al azar:
Ejemplo de cervecería
Mi ejemplo final es una base de datos de cervecería simple:
Esta aplicación permitirá al usuario encontrar cervecerías buscando un nombre. Luego recuperará una lista de cervecerías para que el usuario la vea.
Luego, como ejemplo final, mostraremos un ícono diferente según el país en el que se encuentre la cervecería.
El paso 1 es hacer la Brewery
estructura. Necesitamos hacer que esto se ajuste a Identifiable
fin de poner esta información en una lista.
El paso 2 es crear tres propiedades en la parte superior de nuestra vista de contenido. Uno almacenará la matriz completa de valores devueltos. Esta será una Brewery
matriz. La segunda es la palabra de búsqueda que el usuario escribirá. Finalmente, debajo de esto, declaramos la URL de la API (excluyendo la consulta en sí).
Podemos ver que al combinar the apiURL
y the searchTerm
obtenemos la dirección a usar:
@State var breweries:[Brewery] = []
@State var searchTerm:String = ""
var apiURL:String = "https://api.openbrewerydb.org/breweries/search?query="
El paso 3 es crear la lista que mostrará los resultados. Por ahora, todo lo que mostraremos es el nombre de cada Brewery
fila.
List(breweries) { brewery in
Text(brewery.name ?? "")
}
TextField("Search", text: $searchTerm)
.background(.quaternary)
.cornerRadius(8)
.padding(10)
La segunda mitad de este código es TextField
para que el usuario escriba su consulta de búsqueda.
El paso final de la funcionalidad es configurar el botón de búsqueda. La única diferencia aquí con respecto a lo que hemos hecho antes es que para la Cadena de URL, en lugar de indicar la Cadena aquí para usar, simplemente agregamos el apiURL
y el searchTerm
.
También podemos mejorar nuestro código colocando esta llamada en un do catch
cierre y agregando la declaración de impresión (error). Esto nos permite identificar cuándo hay problemas con la decodificación del objeto JSON en nuestros datos.
Esto puede suceder regularmente con diferentes API y, sin información sobre el error, simplemente devolverá un valor nulo. El error dirá por qué falló, como esperar un tipo de datos diferente.
Button("Find Beer!") {
Task{
do{
let (data, _) = try await URLSession.shared.data(from: URL(string:(apiURL + searchTerm))!)
let decodedResponse = try JSONDecoder().decode([Brewery].self, from: data)
breweries = decodedResponse
}catch{
print("error: ", error)
}
}
}
.buttonStyle(.borderedProminent)
.padding(10)
Al juntar todo esto, obtenemos una aplicación funcional que llamará a un término de búsqueda en la base de datos de la cervecería, devolverá los resultados en una matriz y mostrará los resultados como una lista.
Podemos ir un paso más allá para demostrar que se muestra un elemento adicional si se cumple un criterio.
Por ejemplo aquí, mostraré un emoticón si la cervecería está en los Estados Unidos, y un garabato si no está usando SFSymbols
:
func getIcon(country:String) -> String{
switch country {
case "United States": return "smiley"
default: return "scribble"
}
}
Para hacer esto, simplemente pase el nombre del país y, si el caso coincide con un escenario dado, devuelva la cadena del SFSymbol
. Luego, en el List
, para cada uno brewery
indicamos el nombre, y luego podemos mostrar el Image
siguiente. Aquí está el List
código actualizado:
List(breweries) { brewery in
HStack{
Image(systemName: getIcon(country: brewery.country ?? ""))
Text(brewery.name ?? "")
}
}
El resultado final se parece a esto:
Esta es solo una guía para obtener una aplicación funcional rápida con datos. Puede ver en lo anterior que todo esto se hace en menos de 50 líneas de código. Esto tomará de 10 a 15 minutos para llegar a este punto una vez que tenga confianza y haya practicado, lo que significa que luego puede concentrar su tiempo en mirar colores, espacios, tamaños, símbolos e imágenes.
Las aplicaciones que he creado anteriormente aún no son agradables, y el siguiente paso es practicar esto para ver qué funciona y qué no. Con suerte, lo anterior le brinda los conceptos básicos para mostrar elementos basados en un recibo API. Ahora encuentre algunas API y obtenga programación. Algunas de mis aplicaciones rápidas favoritas se pueden crear mediante API gratuitas que hacen lo siguiente:
Ahora que tienes esto. Mi próximo artículo se concentrará en cómo administrar diferentes formatos y crear temas. Centralizar gran parte de esta información ayudará a crear y modificar vistas desde un solo lugar. Codificación feliz.
1626088193
iOS app development in Singapore
iOS has become the first priority for most smartphone users because of the security it offers compares to the Android operating system. Due to this reason, it is suggested to launch an app in iOS before other platforms.
Want to develop an iOS app in Singapore?
WebClues Infotech with its worldwide reach has already offered its iOS app development services to customers in Singapore. With a highly-skilled development team of 120+ members, WebClues Infotech has got the required resources an agency needs to fulfil client requirements around the world.
Want to know more about our iOS app development services in Singapore?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development in singapore #ios app development company #ios app development #ios #ios app #hire ios developer
1626088709
iOS App Development in the United Arab Emirates
Developed and Developing nations have seen a rapid rise in the demand for iOS app development and the United Arab Emirates is no exception. The use of on-demand apps has increased drastically in the last decade and business is leveraging this demand with launching iOS mobile apps.
Want to develop the iOS app in the United Arab Emirates?
WebClues Infotech after serving multiple clients in UAE has become well aware of the people’s needs in the region. With a highly experienced development team that has completed more than 950+ projects, we are prepared to serve you with your iOS app development needs.
Want to know more about our iOS App Development Services in UAE?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development in the united arab emirates #ios app development #ios app #ios #ios app development company #hire ios developer