A Flutter Package That Help You Create A Verification Input

flutter_verification_code 

A Flutter package that help you create a verification input.

Based on https://github.com/tiny-express/flutter_verification_code_input.

Added state change in case user delete char after complete fill, take a look an example on Stackoverflow

With version 1.1.0 supports copy/paste of entire code

After install, in your Dart code, you can use:

import 'package:flutter_verification_code/flutter_verification_code.dart';

Usage

  VerificationCode(
    textStyle: TextStyle(fontSize: 20.0, color: Colors.red[900]),
    keyboardType: TextInputType.number,
    underlineColor: Colors.amber, // If this is null it will use primaryColor: Colors.red from Theme
    length: 4,
    cursorColor: Colors.blue, // If this is null it will default to the ambient
    // clearAll is NOT required, you can delete it
    // takes any widget, so you can implement your design
    clearAll: Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(
        'clear all',
        style: TextStyle(fontSize: 14.0, decoration: TextDecoration.underline, color: Colors.blue[700]),
      ),
    ),
    onCompleted: (String value) {
      setState(() {
        _code = value;
      });
    },
    onEditing: (bool value) {
      setState(() {
        _onEditing = value;
      });
      if (!_onEditing) FocusScope.of(context).unfocus();
    },
  ),
onEditing: (bool value) {
  setState(() {
    _onEditing = value;
  });
},
Center(
  child: (_onEditing != true)
      ? Text('Your code: $_code')
      : Text('Please enter full code'),
),

Full example is here https://github.com/awaik/flutter_verification_code/tree/master/example

Showcase

Image|100x100, 10%

Image|100x100, 10%

Credits

This is a project by Agoradesk, P2P cryptocurrency trading platform. Created by the team behind LocalMonero, the biggest and most trusted Monero P2P trading platform.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_verification_code

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_verification_code: ^1.1.6

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_verification_code/flutter_verification_code.dart';

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_verification_code/flutter_verification_code.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          primarySwatch: Colors.green,
          primaryColor: Colors.red,
          hintColor: Colors.green),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _onEditing = true;
  String? _code;

  @override
  build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Center(
          child: Text('Example verify code'),
        ),
      ),
      body: Column(
        children: [
          const Padding(
            padding: EdgeInsets.all(8.0),
            child: Center(
              child: Text(
                'Enter your code',
                style: TextStyle(fontSize: 20.0),
              ),
            ),
          ),
          VerificationCode(
            textStyle: Theme.of(context)
                .textTheme
                .bodyText2!
                .copyWith(color: Theme.of(context).primaryColor),
            keyboardType: TextInputType.number,
            underlineColor: Colors
                .amber, // If this is null it will use primaryColor: Colors.red from Theme
            length: 4,
            cursorColor:
                Colors.blue, // If this is null it will default to the ambient
            // clearAll is NOT required, you can delete it
            // takes any widget, so you can implement your design
            clearAll: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                'clear all',
                style: TextStyle(
                    fontSize: 14.0,
                    decoration: TextDecoration.underline,
                    color: Colors.blue[700]),
              ),
            ),
            margin: const EdgeInsets.all(12),
            onCompleted: (String value) {
              setState(() {
                _code = value;
              });
            },
            onEditing: (bool value) {
              setState(() {
                _onEditing = value;
              });
              if (!_onEditing) FocusScope.of(context).unfocus();
            },
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Center(
              child: _onEditing
                  ? const Text('Please enter full code')
                  : Text('Your code: $_code'),
            ),
          )
        ],
      ),
    );
  }
}

Download Details:

Author: agoradesk.com

Source Code: https://github.com/awaik/flutter_verification_code.git

#flutter #android #ios #verified #code #verification 

A Flutter Package That Help You Create A Verification Input

A Fluent, Builder-based Library for Generating Valid Dart Code

Usage

code_builder has a narrow and user-friendly API.

See the example and test folders for additional examples.

For example creating a class with a method:

import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';

void main() {
  final animal = Class((b) => b
    ..name = 'Animal'
    ..extend = refer('Organism')
    ..methods.add(Method.returnsVoid((b) => b
      ..name = 'eat'
      ..body = const Code("print('Yum!');"))));
  final emitter = DartEmitter();
  print(DartFormatter().format('${animal.accept(emitter)}'));
}

Outputs:

class Animal extends Organism {
  void eat() => print('Yum!');
}

Have a complicated set of dependencies for your generated code? code_builder supports automatic scoping of your ASTs to automatically use prefixes to avoid symbol conflicts:

import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';

void main() {
  final library = Library((b) => b.body.addAll([
        Method((b) => b
          ..body = const Code('')
          ..name = 'doThing'
          ..returns = refer('Thing', 'package:a/a.dart')),
        Method((b) => b
          ..body = const Code('')
          ..name = 'doOther'
          ..returns = refer('Other', 'package:b/b.dart')),
      ]));
  final emitter = DartEmitter.scoped();
  print(DartFormatter().format('${library.accept(emitter)}'));
}

Outputs:

import 'package:a/a.dart' as _i1;
import 'package:b/b.dart' as _i2;

_i1.Thing doThing() {}
_i2.Other doOther() {}

Contributing

If a feature is missing (the Dart language is always evolving) or you'd like an easier or better way to do something, consider opening a pull request. You can always file an issue, but generally speaking, feature requests will be on a best-effort basis.

NOTE: Due to the evolving Dart SDK the local dartfmt must be used to format this repository. You can run it simply from the command-line:

$ dart pub run dart_style:format -w .

Updating generated (.g.dart) files

NOTE: There is currently a limitation in build_runner that requires a workaround for developing this package since it is a dependency of the build system.

Make a snapshot of the generated build_runner build script and run from the snapshot instead of from source to avoid problems with deleted files. These steps must be run without deleting the source files.

$ dart run build_runner generate-build-script
$ dart compile kernel .dart_tool/build/entrypoint/build.dart
$ dart .dart_tool/build/entrypoint/build.dill build --delete-conflicting-outputs

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add code_builder

With Flutter:

 $ flutter pub add code_builder

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  code_builder: ^4.4.0

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:code_builder/code_builder.dart';

example/example.dart

// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';

final _dartfmt = DartFormatter();

void main() {
  print('animalClass():\n${'=' * 40}\n${animalClass()}');
  print('scopedLibrary():\n${'=' * 40}\n${scopedLibrary()}');
  print('jsonEnum():\n${'=' * 40}\n${jsonEnum()}');
}

/// Outputs:
///
/// ```dart
/// class Animal extends Organism {
///   void eat() => print('Yum!');
/// }
/// ```
String animalClass() {
  final animal = Class((b) => b
    ..name = 'Animal'
    ..extend = refer('Organism')
    ..methods.add(Method.returnsVoid((b) => b
      ..name = 'eat'
      ..body = refer('print').call([literalString('Yum!')]).code)));
  return _dartfmt.format('${animal.accept(DartEmitter())}');
}

/// Outputs:
///
/// ```dart
/// import 'package:a/a.dart' as _i1;
/// import 'package:b/b.dart' as _i2;
///
/// _i1.Thing doThing() {}
/// _i2.Other doOther() {}
/// ```
String scopedLibrary() {
  final methods = [
    Method((b) => b
      ..body = const Code('')
      ..name = 'doThing'
      ..returns = refer('Thing', 'package:a/a.dart')),
    Method((b) => b
      ..body = const Code('')
      ..name = 'doOther'
      ..returns = refer('Other', 'package:b/b.dart')),
  ];
  final library = Library((b) => b.body.addAll(methods));
  return _dartfmt.format('${library.accept(DartEmitter.scoped())}');
}

/// Outputs:
///
/// ```dart
/// enum Unit {
///  @JsonKey('m')
///  metric,
///  @JsonKey('i')
///  imperial
/// }
/// ```
String jsonEnum() {
  final values = <EnumValue>[
    EnumValue((b) => b
      ..name = 'metric'
      ..annotations.addAll([
        refer('JsonKey').call([literalString('m')])
      ])),
    EnumValue((b) => b
      ..name = 'imperial'
      ..annotations.addAll([
        refer('JsonKey').call([literalString('i')])
      ])),
  ];
  final e = Enum((b) => b
    ..name = 'Unit'
    ..values.addAll(values));
  return _dartfmt.format('${e.accept(DartEmitter())}');
}

Download Details:

Author: tools.dart.dev

Source Code: https://github.com/dart-lang/code_builder

#flutter #android #ios #code #dart #builder #build #gen 

A Fluent, Builder-based Library for Generating Valid Dart Code

Рекурсивный подсчет всех строк кода в каталоге в Linux

Если вы хотите подсчитать строки кода внутри файлов каталога и подкаталога. В этой ситуации вам нужно подсчитывать строки кода из файла, открывая каждый каталог и подкаталог файла? Но для этого в системах Linux, Unix и Python были даны некоторые команды. С помощью которого вы можете сделать это легко.

Подсчитайте все строки кода в каталоге рекурсивно в Linux: В этом руководстве вы узнаете, как рекурсивно подсчитать все строки кода в каталоге.

Как рекурсивно подсчитать все строки кода в каталоге

Используя следующие методы, вы можете рекурсивно подсчитать все строки кода в каталоге:

  • Способ 1: Использование команды wc
  • Способ 2: Использование часов
  • Способ 3: Использование скрипта

Способ 1: Использование команды wc

Самый простой способ рекурсивного подсчета количества строк кода в каталоге — использовать команду wc. Эта команда представляет собой утилиту Unix, которую можно использовать для подсчета количества строк, слов и символов в файле.

Во-первых, откройте окно терминала и перейдите в каталог, в котором вы хотите подсчитать строки кода. Затем выполните следующую команду wc на терминале:

$ find . -name "*.py" -or -name "*.js" -or -name "*.html" | xargs wc -l

Приведенная выше команда найдет/найдет/получит все файлы с расширениями .py, .js и .html в текущем каталоге и его подкаталогах и подсчитает количество строк кода в каждом файле.

Способ 2: Использование часов

Используя командную строку cloc, вы можете подсчитать текущие строки кода и его подкаталоги с различными языками программирования, включая C, C++, Java, JavaScript и Python.

Т

Прежде чем использовать команду cloc, вам необходимо установить ее в своей системе. Скачать последнюю версию cloc можно с его официального сайта ( https://github.com/AlDanial/cloc ).

После того, как вы установили cloc в своей системе. После этого запустите окно терминала и перейдите в каталог, в котором вы хотите подсчитать строки кода. После этого выполните следующую команду cloc в терминале или командной строке:

$ cloc .

Приведенная выше команда cloc — это очень простая команда для подсчета строк кода во всех файлах в текущем каталоге и его подкаталогах и отображения результатов для каждого языка программирования.

Способ 3: Использование скрипта

Если вам нужно больше контроля над процессом подсчета, вы можете написать сценарий для рекурсивного подсчета строк кода в каталоге. Вот пример скрипта, написанного на Python:

import os

def count_lines_of_code(directory):
    total_lines = 0
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(".py") or file.endswith(".js") or file.endswith(".html"):
                filepath = os.path.join(root, file)
                with open(filepath, "r") as f:
                    lines = len(f.readlines())
                    total_lines += lines
    return total_lines

directory = "/path/to/your/directory"
lines_of_code = count_lines_of_code(directory)
print(f"Total lines of code in {directory}: {lines_of_code}")

Этот сценарий использует модуль os для рекурсивного обхода каталога и подсчета строк кода во всех файлах с расширениями .py, .js и .html. Вы можете настроить скрипт для подсчета строк кода на разных языках программирования, изменив расширения файлов в операторе if.

Заключение

Рекурсивный подсчет строк кода в каталоге может быть сложной задачей, но с помощью правильных инструментов и методов это можно сделать легко и эффективно. Независимо от того, используете ли вы команду wc, cloc или пользовательский сценарий, отслеживание количества строк кода в вашем проекте может дать ценную информацию о его сложности, ремонтопригодности и общем состоянии.

Оригинальный источник статьи: https://www.tutsmake.com/

#linux #line #code 

Рекурсивный подсчет всех строк кода в каталоге в Linux

在 Linux 中递归地计算目录中的所有代码行

如果要统计目录和子目录的文件内的代码行数。在这种情况下,您是否必须通过打开文件的每个目录和子目录来计算文件中的代码行数?但是为此,在Linux、Unix、Python系统中已经给出了一些命令。通过使用 which 你可以很容易地做到这一点。

在 Linux 中递归地计算目录中的所有代码行数:在本教程中,您将学习如何递归地计算目录中的所有代码行数。

如何递归地计算目录中的所有代码行数

通过以下方法,可以递归统计目录下的所有代码行数:

  • 方法一:使用wc命令
  • 方法 2:使用 cloc
  • 方法 3:使用脚本

方法一:使用wc命令

递归地计算目录中代码行数的最简单方法是使用 wc 命令。此命令是一个 Unix 实用程序,可用于计算文件中的行数、单词数和字符数。

首先,打开一个终端窗口并导航到要计算代码行数的目录。然后,在终端上执行以下 wc 命令:

$ find . -name "*.py" -or -name "*.js" -or -name "*.html" | xargs wc -l

上面给出的命令将查找/搜索/获取当前目录及其子目录中所有扩展名为 .py、.js 和 .html 的文件,并计算每个文件中的代码行数。

方法 2:使用 cloc

使用 cloc 命令行,您可以使用各种编程语言(包括 C、C++、Java、JavaScript 和 Python)计算当前代码行数及其子目录。

在使用 cloc 命令之前,您需要在您的系统上安装它。您可以从其官方网站( https://github.com/AlDanial/cloc )下载最新版本的 cloc 。

在系统中安装 cloc 后。之后,启动终端窗口并导航到要计算代码行数的目录。之后,在终端或命令行上执行以下 cloc 命令:

$ cloc .

上面给出的 cloc 命令是一个非常简单的命令,用于计算当前目录及其子目录中所有文件的代码行数,并显示每种编程语言的结果。

方法 3:使用脚本

如果您需要更多地控制计数过程,您可以编写一个脚本来递归地计算目录中的代码行数。这是一个用 Python 编写的示例脚本:

import os

def count_lines_of_code(directory):
    total_lines = 0
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(".py") or file.endswith(".js") or file.endswith(".html"):
                filepath = os.path.join(root, file)
                with open(filepath, "r") as f:
                    lines = len(f.readlines())
                    total_lines += lines
    return total_lines

directory = "/path/to/your/directory"
lines_of_code = count_lines_of_code(directory)
print(f"Total lines of code in {directory}: {lines_of_code}")

此脚本使用 os 模块递归遍历目录并统计所有扩展名为 .py、.js 和 .html 的文件中的代码行数。您可以通过更改 if 语句中的文件扩展名来自定义脚本以计算不同编程语言的代码行数。

结论

递归地计算目录中的代码行数可能是一项具有挑战性的任务,但使用正确的工具和技术,可以轻松高效地完成这项工作。无论您选择使用 wc 命令、cloc 还是自定义脚本,跟踪项目中的代码行数都可以提供有关其复杂性、可维护性和整体健康状况的宝贵见解。

文章原文出处:https: //www.tutsmake.com/

#linux #line #code 

在 Linux 中递归地计算目录中的所有代码行

Count All the Lines of Code in a Directory Recursively in Linux

If you want to count the lines of code inside the files of a directory and subdirectory. In this situation do you have to count the lines of code from a file by opening each directory and subdirectory of the file? But for this, some commands have been given in Linux, Unix, and Python systems. By using which you can do this easily.

Count all the lines of code in a directory recursively in linux: In this tutorial, you will learn how to count all the lines of code in a directory recursively.

How to Count All the Lines of Code in a Directory Recursively

By using the following methods, you can count all the lines of code in directory recursively:

  • Method 1: Using the wc command
  • Method 2: Using cloc
  • Method 3: Using a script

Method 1: Using the wc command

Using the simplest way to count the number of lines of code in a directory recursively is by using the wc command. This command is a Unix utility that can be used to count the number of lines, words, and characters in a file.

Firstly, open a terminal window and navigate to the directory, in which you want to count the lines of code in. Then, execute the following wc command on terminal:

$ find . -name "*.py" -or -name "*.js" -or -name "*.html" | xargs wc -l

The above-given command will find/search/get for all files with the .py, .js, and .html extensions in the current directory and its subdirectories and count the number of lines of code in each file.

Method 2: Using cloc

Using the cloc command line, you can count the lines of code current and it’s subdirectories with a variety of programming languages, including C, C++, Java, JavaScript, and Python.

T

Before use the cloc command, you need to install it on your system. You can download the latest version of cloc from its official website (https://github.com/AlDanial/cloc).

Once you have installed cloc in your system. After that, start a terminal window and navigate to the directory, in which you want to count the lines of code in. After that, execute the following cloc command on terminal or command line:

$ cloc .

The above given cloc command is a very simple command for counting the lines of code in all the files in the current directory and its subdirectories and display the results for each programming language.

Method 3: Using a script

If you need more control over the counting process, you can write a script to count the lines of code in a directory recursively. Here is an example script written in Python:

import os

def count_lines_of_code(directory):
    total_lines = 0
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(".py") or file.endswith(".js") or file.endswith(".html"):
                filepath = os.path.join(root, file)
                with open(filepath, "r") as f:
                    lines = len(f.readlines())
                    total_lines += lines
    return total_lines

directory = "/path/to/your/directory"
lines_of_code = count_lines_of_code(directory)
print(f"Total lines of code in {directory}: {lines_of_code}")

This script uses the os module to traverse the directory recursively and count the lines of code in all the files with the .py, .js, and .html extensions. You can customize the script to count the lines of code in different programming languages by changing the file extensions in the if statement.

Conclusion

Counting the lines of code in a directory recursively can be a challenging task, but with the right tools and techniques, it can be done easily and efficiently. Whether you choose to use the wc command, cloc, or a custom script, tracking the number of lines of code in your project can provide valuable insights into its complexity, maintainability, and overall health.

Original article source at: https://www.tutsmake.com/

#linux #line #code 

Count All the Lines of Code in a Directory Recursively in Linux

Code Generator for MobX in Dart

mobx_codegen

MobX Code Generation library

Adds support for annotating your MobX code with @observable, @computed, @action, making it super simple to use MobX.

Note that these annotations only work inside store-classes.

store-classes are abstract and use the Store mixin. When you run the build_runner, it will automatically generate the *.g.dart file that must be imported in your file.

$> cd $YOUR_PROJECT_DIR
$> flutter packages pub run build_runner build

Example

import 'package:mobx/mobx.dart';

// Include generated file
part 'todos.g.dart';

// This is the class used by rest of your codebase
class Todo = TodoBase with _$Todo;

// The store-class
abstract class TodoBase with Store {
  TodoBase(this.description);

  @observable
  String description = '';

  @observable
  bool done = false;
}

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add mobx_codegen

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  mobx_codegen: ^2.2.0

Alternatively, your editor might support dart pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:mobx_codegen/mobx_codegen.dart';

example/README.md

Using mobx_codegen

Refer to this Getting Started guide for using mobx_codegen with mobx.

Download Details:

Author: dart.pixelingene.com

Source Code: https://github.com/mobxjs/mobx.dart

#flutter #mobx #code #gen 

Code Generator for MobX in Dart

Как повторять код Python до тех пор, пока он не сработает

Используйте библиотеки Tenacity и Mock, чтобы найти ошибки, скрывающиеся глубоко в вашем коде.

Иногда функция вызывается с неверными входными данными или с неверным состоянием программы, что приводит к сбою. В таких языках, как Python, это обычно приводит к исключению.

Но иногда исключения вызваны другими проблемами или носят временный характер. Представьте себе код, который должен продолжать работать, несмотря на очистку кэшированных данных. Теоретически код и очиститель могли бы тщательно согласовать методологию очистки, чтобы предотвратить попытки кода получить доступ к несуществующему файлу или каталогу. К сожалению, такой подход сложен и подвержен ошибкам. Однако большинство этих проблем носят временный характер, так как очиститель в конечном итоге создаст правильные структуры.

Еще чаще неопределенный характер сетевого программирования означает, что некоторые функции, абстрагирующие сетевой вызов, дают сбой из-за потери или повреждения пакетов.

Обычное решение — повторить неудачный код. Эта практика позволяет пропустить прошлые переходные проблемы, но при этом (в конечном итоге) потерпеть неудачу, если проблема не устранена. В Python есть несколько библиотек, облегчающих повторную попытку. Это обычное «упражнение для пальцев».

упорство

Одна библиотека, которая выходит за рамки упражнения пальцами и превращается в полезную абстракцию, — это упорство . Установите его с помощью pip install tenacityили зависите от него, используя dependencies = tenacityстроку в вашем pyproject.tomlфайле.

Настроить ведение журнала

Удобная встроенная функция — tenacityподдержка ведения журнала. При обработке ошибок просмотр подробностей журнала о повторных попытках имеет неоценимое значение.

Чтобы в оставшихся примерах отображались сообщения журнала, настройте библиотеку ведения журнала . В реальной программе это делает центральная точка входа или плагин конфигурации логирования. Вот пример:

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(name)s:%(levelname)s:%(message)s",
)

TENACITY_LOGGER = logging.getLogger("Retrying")

Выборочный отказ

Чтобы продемонстрировать возможности tenacity, полезно несколько раз потерпеть неудачу, прежде чем добиться успеха. Использование unittest.mockполезно для этого сценария.

from unittest import mock

thing = mock.MagicMock(side_effect=[ValueError(), ValueError(), 3])

Если вы новичок в модульном тестировании, прочитайте мою статью о mock .

Прежде чем демонстрировать мощь tenacity, посмотрите, что происходит, когда вы реализуете повтор непосредственно внутри функции. Демонстрация этого позволяет легко увидеть ручную работу с использованием tenacityсохранений.

def useit(a_thing):
    for i in range(3):
        try:
            value = a_thing()
        except ValueError:
            TENACITY_LOGGER.info("Recovering")
            continue
        else:
            break
    else:
        raise ValueError()
    print("the value is", value)

Функцию можно вызвать с чем-то, что никогда не дает сбоев:

>>> useit(lambda: 5)
the value is 5

С в конечном итоге успешной вещью:

>>> useit(thing)

2023-03-29 17:00:42,774:Retrying:INFO:Recovering
2023-03-29 17:00:42,779:Retrying:INFO:Recovering

the value is 3

Вызов функции с чем-то, что терпит неудачу слишком много раз, заканчивается плохо:

try:
    useit(mock.MagicMock(side_effect=[ValueError()] * 5 + [4]))
except Exception as exc:
    print("could not use it", repr(exc))

Результат:


2023-03-29 17:00:46,763:Retrying:INFO:Recovering
2023-03-29 17:00:46,767:Retrying:INFO:Recovering
2023-03-29 17:00:46,770:Retrying:INFO:Recovering

could not use it ValueError()

Простое использование упорства

По большей части вышеприведенная функция повторяла код. Следующий шаг — заставить декоратор обрабатывать логику повторных попыток:

import tenacity

my_retry=tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
)

Tenacity поддерживает заданное количество попыток и протоколирование после получения исключения.

Функция useitбольше не должна заботиться о повторных попытках. Иногда для функции имеет смысл все еще учитывать возможность повторного запуска . Tenacity позволяет коду самостоятельно определять возможность повторного запуска, вызывая специальное исключение TryAgain:

@my_retry
def useit(a_thing):
    try:
        value = a_thing()
    except ValueError:
        raise tenacity.TryAgain()
    print("the value is", value)

Теперь при вызове useitон повторяет попытку ValueErrorбез специального кода повторной попытки:

useit(mock.MagicMock(side_effect=[ValueError(), ValueError(), 2]))

Выход:

2023-03-29 17:12:19,074:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 17:12:19,080:Retrying:WARNING:Finished call to '__main__.useit' after 0.006(s), this was the 2nd time calling it.

the value is 2

Настройте декоратор

Приведенный выше декоратор — лишь небольшой пример того, что tenacityподдерживает. Вот более сложный декоратор:

my_retry = tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

Это более реалистичный пример декоратора с дополнительными параметрами:

  • before: Журнал перед вызовом функции
  • retry: вместо повторной попытки TryAgainповторять исключения с заданными критериями
  • wait: ожидание между звонками (это особенно важно, если вы звоните в службу)
  • reraise: если повторная попытка не удалась, повторно вызвать исключение последней попытки.

Теперь, когда декоратор также указывает возможность повторной попытки, удалите код из useit:

@my_retry
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

Вот как это работает:

useit(mock.MagicMock(side_effect=[ValueError(), 5]))

Выход:

2023-03-29 17:19:39,820:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:19:39,823:Retrying:WARNING:Finished call to '__main__.useit' after 0.003(s), this was the 1st time calling it.
2023-03-29 17:19:40,829:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.


the value is 5

Обратите внимание на временную задержку между второй и третьей строками журнала. Это почти ровно одна секунда:

>>> useit(mock.MagicMock(side_effect=[5]))

2023-03-29 17:20:25,172:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

the value is 5

Подробнее:

try:
    useit(mock.MagicMock(side_effect=[ValueError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

Выход:

2023-03-29 17:21:22,884:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:21:22,888:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 1st time calling it.
2023-03-29 17:21:23,892:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.
2023-03-29 17:21:23,894:Retrying:WARNING:Finished call to '__main__.useit' after 1.010(s), this was the 2nd time calling it.
2023-03-29 17:21:25,896:Retrying:WARNING:Starting call to '__main__.useit', this is the 3rd time calling it.
2023-03-29 17:21:25,899:Retrying:WARNING:Finished call to '__main__.useit' after 3.015(s), this was the 3rd time calling it.

retrying failed ValueError('detailed reason')

Опять же, с KeyErrorвместо ValueError:

try:
    useit(mock.MagicMock(side_effect=[KeyError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

Выход:

2023-03-29 17:21:37,345:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

retrying failed KeyError('detailed reason')

Отделить декоратор от контроллера

Часто одни и те же параметры повторной попытки требуются повторно. В этих случаях лучше всего создать контроллер повторных попыток с параметрами:

my_retryer = tenacity.Retrying(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

Украсьте функцию контроллером повторных попыток:

@my_retryer.wraps
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

Запустить его:

>>> useit(mock.MagicMock(side_effect=[ValueError(), 5]))

2023-03-29 17:29:25,656:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:29:25,663:Retrying:WARNING:Finished call to '__main__.useit' after 0.008(s), this was the 1st time calling it.
2023-03-29 17:29:26,667:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.

the value is 5

Это позволяет собирать статистику последнего звонка:

>>> my_retryer.statistics

{'start_time': 26782.847558759,
 'attempt_number': 2,
 'idle_for': 1.0,
 'delay_since_first_attempt': 0.0075125470029888675}

Используйте эту статистику для обновления внутреннего реестра статистики и интеграции с вашей системой мониторинга.

Продлите упорство

Многие из аргументов декоратора являются объектами. Эти объекты могут быть объектами подклассов, что обеспечивает глубокую расширяемость.

Например, предположим, что последовательность Фибоначчи должна определять время ожидания. Суть в том, что API для запроса времени ожидания дает только номер попытки, поэтому обычный итеративный способ вычисления Фибоначчи бесполезен.

Одним из способов достижения цели является использование закрытой формулы :

Замкнутая формула для последовательности Фибоначчи, записанная в LaTeX как $(((1+\sqrt{5})/2)^n - ((1-\sqrt{5})/2)^n)/\sqrt{5 }$

Малоизвестный трюк — пропустить вычитание в пользу округления до ближайшего целого числа:

Формула варианта для последовательности Фибоначчи, записанная в LaTeX как $\operatorname{round}((((1+\sqrt{5})/2)^n)/\sqrt{5})$

Что переводится на Python как:

int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

Это можно использовать непосредственно в функции Python:

from math import sqrt

def fib(n):
    return int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

Последовательность Фибоначчи отсчитывается, 0а номера попыток начинаются с 1, поэтому waitфункция должна компенсировать это:

def wait_fib(rcs):
    return fib(rcs.attempt_number - 1)

Функцию можно передать напрямую как waitпараметр:

@tenacity.retry(
    stop=tenacity.stop_after_attempt(7),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    wait=wait_fib,
)
def useit(thing):
    print("value is", thing())
try:
    useit(mock.MagicMock(side_effect=[tenacity.TryAgain()] * 7))
except Exception as exc:
    pass

Попробуйте:

2023-03-29 18:03:52,783:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 18:03:52,787:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 2nd time calling it.
2023-03-29 18:03:53,789:Retrying:WARNING:Finished call to '__main__.useit' after 1.006(s), this was the 3rd time calling it.
2023-03-29 18:03:54,793:Retrying:WARNING:Finished call to '__main__.useit' after 2.009(s), this was the 4th time calling it.
2023-03-29 18:03:56,797:Retrying:WARNING:Finished call to '__main__.useit' after 4.014(s), this was the 5th time calling it.
2023-03-29 18:03:59,800:Retrying:WARNING:Finished call to '__main__.useit' after 7.017(s), this was the 6th time calling it.
2023-03-29 18:04:04,806:Retrying:WARNING:Finished call to '__main__.useit' after 12.023(s), this was the 7th time calling it.

Вычтите последующие числа из времени «после» и округляйте, чтобы увидеть последовательность Фибоначчи:

intervals = [
    0.000,
    0.004,
    1.006,
    2.009,
    4.014,
    7.017,
    12.023,
]
for x, y in zip(intervals[:-1], intervals[1:]):
    print(int(y-x), end=" ")

Это работает? Да, именно так, как и ожидалось:

0 1 1 2 3 5 

Заворачивать

Написание специального кода повторных попыток может быть забавным отвлечением. Для производственного кода лучшим выбором будет проверенная библиотека, такая как tenacity. Библиотека tenacityнастраивается и расширяется, и, скорее всего, она удовлетворит ваши потребности.

Оригинальный источник статьи: https://opensource.com/

#python #code #fail 

Как повторять код Python до тех пор, пока он не сработает
田辺  桃子

田辺 桃子

1682477823

如何重试 Python 代码直到失败

使用 Tenacity 和 Mock 库查找隐藏在代码深处的错误。

有时,一个函数在错误的输入或错误的程序状态下被调用,因此它会失败。在像 Python 这样的语言中,这通常会导致异常。

但有时异常是由不同的问题引起的或者是暂时的。想象一下,面对正在清理的缓存数据,代码必须继续工作。理论上,代码和清理器可以谨慎地就清理方法达成一致,以防止代码尝试访问不存在的文件或目录。不幸的是,这种方法很复杂而且容易出错。然而,大多数这些问题都是暂时的,因为清洁工最终会创造出正确的结构。

更常见的是,网络编程的不确定性意味着一些抽象网络调用的函数会因为数据包丢失或损坏而失败。

一个常见的解决方案是重试失败的代码。这种做法允许跳过过去的过渡问题,但如果问题仍然存在,仍然(最终)失败。Python 有几个库可以使重试更容易。这是一个常见的“手指练习”。

韧性

一个超越手指练习并进入有用抽象的库是tenacity。使用文件中的一行安装它pip install tenacity或依赖它。dependencies = tenacitypyproject.toml

设置日志记录

一个方便的内置功能tenacity是支持日志记录。通过错误处理,查看有关重试尝试的日志详细信息是非常宝贵的。

要允许其余示例显示日志消息,请设置日志库。在实际程序中,中央入口点或日志配置插件会执行此操作。这是一个示例:

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(name)s:%(levelname)s:%(message)s",
)

TENACITY_LOGGER = logging.getLogger("Retrying")

选择性失败

为了演示 的功能tenacity,在最终成功之前有一种失败几次的方法是很有帮助的。使用unittest.mock对于这种情况很有用。

from unittest import mock

thing = mock.MagicMock(side_effect=[ValueError(), ValueError(), 3])

如果您不熟悉单元测试,请阅读我关于 mock 的文章

在展示 的强大功能之前tenacity,先看看当您直接在函数内部实现重试时会发生什么。演示这一点可以很容易地看到使用tenacity保存的手动工作。

def useit(a_thing):
    for i in range(3):
        try:
            value = a_thing()
        except ValueError:
            TENACITY_LOGGER.info("Recovering")
            continue
        else:
            break
    else:
        raise ValueError()
    print("the value is", value)

该函数可以用永不失败的东西调用:

>>> useit(lambda: 5)
the value is 5

随着最终成功的事情:

>>> useit(thing)

2023-03-29 17:00:42,774:Retrying:INFO:Recovering
2023-03-29 17:00:42,779:Retrying:INFO:Recovering

the value is 3

用失败太多次的东西调用函数,结果很糟糕:

try:
    useit(mock.MagicMock(side_effect=[ValueError()] * 5 + [4]))
except Exception as exc:
    print("could not use it", repr(exc))

结果:


2023-03-29 17:00:46,763:Retrying:INFO:Recovering
2023-03-29 17:00:46,767:Retrying:INFO:Recovering
2023-03-29 17:00:46,770:Retrying:INFO:Recovering

could not use it ValueError()

简单的韧性用法

在大多数情况下,上面的函数是重试代码。下一步是让装饰器处理重试逻辑:

import tenacity

my_retry=tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
)

Tenacity 支持在获取异常后进行指定次数的尝试和记录。

useit功能不再需要关心重试。有时函数仍然考虑可重试性是有意义的。Tenacity 允许代码通过引发特殊异常自行确定可重试性TryAgain

@my_retry
def useit(a_thing):
    try:
        value = a_thing()
    except ValueError:
        raise tenacity.TryAgain()
    print("the value is", value)

现在调用时useitValueError无需自定义重试代码即可重试:

useit(mock.MagicMock(side_effect=[ValueError(), ValueError(), 2]))

输出:

2023-03-29 17:12:19,074:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 17:12:19,080:Retrying:WARNING:Finished call to '__main__.useit' after 0.006(s), this was the 2nd time calling it.

the value is 2

配置装饰器

上面的装饰器只是tenacity支持的一小部分。这是一个更复杂的装饰器:

my_retry = tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

这是一个带有附加参数的更真实的装饰器示例:

  • before: 调用函数前记录
  • retry: 而不是只重试TryAgain,重试具有给定条件的异常
  • wait:在调用之间等待(如果调用服务,这尤其重要)
  • reraise: 如果重试失败,重新引发上次尝试的异常

现在装饰器还指定了可重试性,从中删除代码useit

@my_retry
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

它是这样工作的:

useit(mock.MagicMock(side_effect=[ValueError(), 5]))

输出:

2023-03-29 17:19:39,820:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:19:39,823:Retrying:WARNING:Finished call to '__main__.useit' after 0.003(s), this was the 1st time calling it.
2023-03-29 17:19:40,829:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.


the value is 5

注意第二个和第三个日志行之间的时间延迟。几乎正好是一秒钟:

>>> useit(mock.MagicMock(side_effect=[5]))

2023-03-29 17:20:25,172:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

the value is 5

更多细节:

try:
    useit(mock.MagicMock(side_effect=[ValueError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

输出:

2023-03-29 17:21:22,884:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:21:22,888:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 1st time calling it.
2023-03-29 17:21:23,892:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.
2023-03-29 17:21:23,894:Retrying:WARNING:Finished call to '__main__.useit' after 1.010(s), this was the 2nd time calling it.
2023-03-29 17:21:25,896:Retrying:WARNING:Starting call to '__main__.useit', this is the 3rd time calling it.
2023-03-29 17:21:25,899:Retrying:WARNING:Finished call to '__main__.useit' after 3.015(s), this was the 3rd time calling it.

retrying failed ValueError('detailed reason')

同样,用KeyError而不是ValueError

try:
    useit(mock.MagicMock(side_effect=[KeyError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

输出:

2023-03-29 17:21:37,345:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

retrying failed KeyError('detailed reason')

将装饰器与控制器分离

通常,重复需要类似的重试参数。在这些情况下,最好使用以下参数创建重试控制器:

my_retryer = tenacity.Retrying(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

用重试控制器修饰函数:

@my_retryer.wraps
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

运行:

>>> useit(mock.MagicMock(side_effect=[ValueError(), 5]))

2023-03-29 17:29:25,656:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:29:25,663:Retrying:WARNING:Finished call to '__main__.useit' after 0.008(s), this was the 1st time calling it.
2023-03-29 17:29:26,667:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.

the value is 5

这使您可以收集上次调用的统计信息:

>>> my_retryer.statistics

{'start_time': 26782.847558759,
 'attempt_number': 2,
 'idle_for': 1.0,
 'delay_since_first_attempt': 0.0075125470029888675}

使用这些统计信息来更新内部统计信息注册表并与您的监控框架集成。

延展韧性

装饰器的许多参数都是对象。这些对象可以是子类的对象,允许深度扩展。

例如,假设斐波那契数列应该确定等待时间。不同之处在于,请求等待时间的 API 仅提供尝试次数,因此通常的迭代计算 Fibonacci 的方法没有用。

实现目标的一种方法是使用封闭公式

斐波那契数列的闭合公式,在 LaTeX 中写为 $(((1+\sqrt{5})/2)^n - ((1-\sqrt{5})/2)^n)/\sqrt{5 }$

一个鲜为人知的技巧是跳过减法,转而舍入到最接近的整数:

斐波那契数列的变体公式,在 LaTeX 中写为 $\operatorname{round}((((1+\sqrt{5})/2)^n)/\sqrt{5})$

将其转换为 Python 为:

int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

这可以直接在 Python 函数中使用:

from math import sqrt

def fib(n):
    return int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

斐波那契数列从0开始计数,而尝试次数从 开始1,因此wait需要一个函数对此进行补偿:

def wait_fib(rcs):
    return fib(rcs.attempt_number - 1)

该函数可以直接作为参数传递wait

@tenacity.retry(
    stop=tenacity.stop_after_attempt(7),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    wait=wait_fib,
)
def useit(thing):
    print("value is", thing())
try:
    useit(mock.MagicMock(side_effect=[tenacity.TryAgain()] * 7))
except Exception as exc:
    pass

试试看:

2023-03-29 18:03:52,783:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 18:03:52,787:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 2nd time calling it.
2023-03-29 18:03:53,789:Retrying:WARNING:Finished call to '__main__.useit' after 1.006(s), this was the 3rd time calling it.
2023-03-29 18:03:54,793:Retrying:WARNING:Finished call to '__main__.useit' after 2.009(s), this was the 4th time calling it.
2023-03-29 18:03:56,797:Retrying:WARNING:Finished call to '__main__.useit' after 4.014(s), this was the 5th time calling it.
2023-03-29 18:03:59,800:Retrying:WARNING:Finished call to '__main__.useit' after 7.017(s), this was the 6th time calling it.
2023-03-29 18:04:04,806:Retrying:WARNING:Finished call to '__main__.useit' after 12.023(s), this was the 7th time calling it.

从“之后”的时间和舍入中减去后续数字以查看斐波那契数列:

intervals = [
    0.000,
    0.004,
    1.006,
    2.009,
    4.014,
    7.017,
    12.023,
]
for x, y in zip(intervals[:-1], intervals[1:]):
    print(int(y-x), end=" ")

它有效吗?是的,完全符合预期:

0 1 1 2 3 5 

包起来

编写临时重试代码可能会让人分心。对于生产级代码,更好的选择是经过验证的库,例如tenacity. 该tenacity库是可配置和可扩展的,很可能会满足您的需要。

文章原文出处:https: //opensource.com/

#python #code #fail 

如何重试 Python 代码直到失败
Gordon  Taylor

Gordon Taylor

1682473872

How to Retry Your Python Code Until It Fails

Use the Tenacity and Mock libraries to find the bugs hiding deep within your code.

Sometimes, a function is called with bad inputs or in a bad program state, so it fails. In languages like Python, this usually results in an exception.

But sometimes exceptions are caused by different issues or are transitory. Imagine code that must keep working in the face of caching data being cleaned up. In theory, the code and the cleaner could carefully agree on the clean-up methodology to prevent the code from trying to access a non-existing file or directory. Unfortunately, that approach is complicated and error-prone. However, most of these problems are transitory, as the cleaner will eventually create the correct structures.

Even more frequently, the uncertain nature of network programming means that some functions that abstract a network call fail because packets were lost or corrupted.

A common solution is to retry the failing code. This practice allows skipping past transitional problems while still (eventually) failing if the issue persists. Python has several libraries to make retrying easier. This is a common "finger exercise."

Tenacity

One library that goes beyond a finger exercise and into useful abstraction is tenacity. Install it with pip install tenacity or depend on it using a dependencies = tenacity line in your pyproject.toml file.

Set up logging

A handy built-in feature of tenacity is support for logging. With error handling, seeing log details about retry attempts is invaluable.

To allow the remaining examples display log messages, set up the logging library. In a real program, the central entry point or a logging configuration plugin does this. Here's a sample:

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(name)s:%(levelname)s:%(message)s",
)

TENACITY_LOGGER = logging.getLogger("Retrying")

Selective failure

To demonstrate the features of tenacity, it's helpful to have a way to fail a few times before finally succeeding. Using unittest.mock is useful for this scenario.

from unittest import mock

thing = mock.MagicMock(side_effect=[ValueError(), ValueError(), 3])

If you're new to unit testing, read my article on mock.

Before showing the power of tenacity, look at what happens when you implement retrying directly inside a function. Demonstrating this makes it easy to see the manual effort using tenacity saves.

def useit(a_thing):
    for i in range(3):
        try:
            value = a_thing()
        except ValueError:
            TENACITY_LOGGER.info("Recovering")
            continue
        else:
            break
    else:
        raise ValueError()
    print("the value is", value)

The function can be called with something that never fails:

>>> useit(lambda: 5)
the value is 5

With the eventually-successful thing:

>>> useit(thing)

2023-03-29 17:00:42,774:Retrying:INFO:Recovering
2023-03-29 17:00:42,779:Retrying:INFO:Recovering

the value is 3

Calling the function with something that fails too many times ends poorly:

try:
    useit(mock.MagicMock(side_effect=[ValueError()] * 5 + [4]))
except Exception as exc:
    print("could not use it", repr(exc))

The result:


2023-03-29 17:00:46,763:Retrying:INFO:Recovering
2023-03-29 17:00:46,767:Retrying:INFO:Recovering
2023-03-29 17:00:46,770:Retrying:INFO:Recovering

could not use it ValueError()

Simple tenacity usage

For the most part, the function above was retrying code. The next step is to have a decorator handle the retrying logic:

import tenacity

my_retry=tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
)

Tenacity supports a specified number of attempts and logging after getting an exception.

The useit function no longer has to care about retrying. Sometimes it makes sense for the function to still consider retryability. Tenacity allows code to determine retryability by itself by raising the special exception TryAgain:

@my_retry
def useit(a_thing):
    try:
        value = a_thing()
    except ValueError:
        raise tenacity.TryAgain()
    print("the value is", value)

Now when calling useit, it retries ValueError without needing custom retrying code:

useit(mock.MagicMock(side_effect=[ValueError(), ValueError(), 2]))

The output:

2023-03-29 17:12:19,074:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 17:12:19,080:Retrying:WARNING:Finished call to '__main__.useit' after 0.006(s), this was the 2nd time calling it.

the value is 2

Configure the decorator

The decorator above is just a small sample of what tenacity supports. Here's a more complicated decorator:

my_retry = tenacity.retry(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

This is a more realistic decorator example with additional parameters:

  • before: Log before calling the function
  • retry: Instead of only retrying TryAgain, retry exceptions with the given criteria
  • wait: Wait between calls (this is especially important if calling out to a service)
  • reraise: If retrying failed, reraise the last attempt's exception

Now that the decorator also specifies retryability, remove the code from useit:

@my_retry
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

Here's how it works:

useit(mock.MagicMock(side_effect=[ValueError(), 5]))

The output:

2023-03-29 17:19:39,820:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:19:39,823:Retrying:WARNING:Finished call to '__main__.useit' after 0.003(s), this was the 1st time calling it.
2023-03-29 17:19:40,829:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.


the value is 5

Notice the time delay between the second and third log lines. It's almost exactly one second:

>>> useit(mock.MagicMock(side_effect=[5]))

2023-03-29 17:20:25,172:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

the value is 5

With more detail:

try:
    useit(mock.MagicMock(side_effect=[ValueError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

The output:

2023-03-29 17:21:22,884:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:21:22,888:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 1st time calling it.
2023-03-29 17:21:23,892:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.
2023-03-29 17:21:23,894:Retrying:WARNING:Finished call to '__main__.useit' after 1.010(s), this was the 2nd time calling it.
2023-03-29 17:21:25,896:Retrying:WARNING:Starting call to '__main__.useit', this is the 3rd time calling it.
2023-03-29 17:21:25,899:Retrying:WARNING:Finished call to '__main__.useit' after 3.015(s), this was the 3rd time calling it.

retrying failed ValueError('detailed reason')

Again, with KeyError instead of ValueError:

try:
    useit(mock.MagicMock(side_effect=[KeyError("detailed reason")]*3))
except Exception as exc:
    print("retrying failed", repr(exc))

The output:

2023-03-29 17:21:37,345:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.

retrying failed KeyError('detailed reason')

Separate the decorator from the controller

Often, similar retrying parameters are needed repeatedly. In these cases, it's best to create a retrying controller with the parameters:

my_retryer = tenacity.Retrying(
    stop=tenacity.stop_after_attempt(3),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    before=tenacity.before_log(TENACITY_LOGGER, logging.WARNING),
    retry=tenacity.retry_if_exception_type(ValueError),
    wait=tenacity.wait_incrementing(1, 10, 2),
    reraise=True
)

Decorate the function with the retrying controller:

@my_retryer.wraps
def useit(a_thing):
    value = a_thing()
    print("the value is", value)

Run it:

>>> useit(mock.MagicMock(side_effect=[ValueError(), 5]))

2023-03-29 17:29:25,656:Retrying:WARNING:Starting call to '__main__.useit', this is the 1st time calling it.
2023-03-29 17:29:25,663:Retrying:WARNING:Finished call to '__main__.useit' after 0.008(s), this was the 1st time calling it.
2023-03-29 17:29:26,667:Retrying:WARNING:Starting call to '__main__.useit', this is the 2nd time calling it.

the value is 5

This lets you gather the statistics of the last call:

>>> my_retryer.statistics

{'start_time': 26782.847558759,
 'attempt_number': 2,
 'idle_for': 1.0,
 'delay_since_first_attempt': 0.0075125470029888675}

Use these statistics to update an internal statistics registry and integrate with your monitoring framework.

Extend tenacity

Many of the arguments to the decorator are objects. These objects can be objects of subclasses, allowing deep extensionability.

For example, suppose the Fibonacci sequence should determine the wait times. The twist is that the API for asking for wait time only gives the attempt number, so the usual iterative way of calculating Fibonacci is not useful.

One way to accomplish the goal is to use the closed formula:

Closed formula for a Fibonacci sequence, written in LaTeX as $(((1+\sqrt{5})/2)^n - ((1-\sqrt{5})/2)^n)/\sqrt{5}$

A little-known trick is skipping the subtraction in favor of rounding to the closest integer:

Variant formula for a Fibonacci sequence, written in LaTeX as $\operatorname{round}((((1+\sqrt{5})/2)^n)/\sqrt{5})$

Which translates to Python as:

int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

This can be used directly in a Python function:

from math import sqrt

def fib(n):
    return int(((1 + sqrt(5))/2)**n / sqrt(5) + 0.5)

The Fibonacci sequence counts from 0 while the attempt numbers start at 1, so a wait function needs to compensate for that:

def wait_fib(rcs):
    return fib(rcs.attempt_number - 1)

The function can be passed directly as the wait parameter:

@tenacity.retry(
    stop=tenacity.stop_after_attempt(7),
    after=tenacity.after_log(TENACITY_LOGGER, logging.WARNING),
    wait=wait_fib,
)
def useit(thing):
    print("value is", thing())
try:
    useit(mock.MagicMock(side_effect=[tenacity.TryAgain()] * 7))
except Exception as exc:
    pass

Try it out:

2023-03-29 18:03:52,783:Retrying:WARNING:Finished call to '__main__.useit' after 0.000(s), this was the 1st time calling it.
2023-03-29 18:03:52,787:Retrying:WARNING:Finished call to '__main__.useit' after 0.004(s), this was the 2nd time calling it.
2023-03-29 18:03:53,789:Retrying:WARNING:Finished call to '__main__.useit' after 1.006(s), this was the 3rd time calling it.
2023-03-29 18:03:54,793:Retrying:WARNING:Finished call to '__main__.useit' after 2.009(s), this was the 4th time calling it.
2023-03-29 18:03:56,797:Retrying:WARNING:Finished call to '__main__.useit' after 4.014(s), this was the 5th time calling it.
2023-03-29 18:03:59,800:Retrying:WARNING:Finished call to '__main__.useit' after 7.017(s), this was the 6th time calling it.
2023-03-29 18:04:04,806:Retrying:WARNING:Finished call to '__main__.useit' after 12.023(s), this was the 7th time calling it.

Subtract subsequent numbers from the "after" time and round to see the Fibonacci sequence:

intervals = [
    0.000,
    0.004,
    1.006,
    2.009,
    4.014,
    7.017,
    12.023,
]
for x, y in zip(intervals[:-1], intervals[1:]):
    print(int(y-x), end=" ")

Does it work? Yes, exactly as expected:

0 1 1 2 3 5 

Wrap up

Writing ad-hoc retry code can be a fun distraction. For production-grade code, a better choice is a proven library like tenacity. The tenacity library is configurable and extendable, and it will likely meet your needs.

Original article source at: https://opensource.com/

#python #code #fail 

How to Retry Your Python Code Until It Fails
Corey Brooks

Corey Brooks

1682050674

Vim in VS Code

Learn how to leverage the power of Vim keybindings and commands within VS Code to enhance your productivity and streamline your workflow. Real-world use cases, time-saving tips, and best practices that bring Vim's efficiency to your VS Code experience. 

Vim in VS Code

Dive into 'Vim in VS Code' and discover practical Vim techniques seamlessly integrated into today's modern coding environment. Join our livestream as we showcase how to leverage the power of Vim keybindings and commands within VS Code to enhance your productivity and streamline your workflow. Learn from our expert hosts as they demonstrate real-world use cases, time-saving tips, and best practices that bring Vim's efficiency to your VS Code experience. Don't miss this opportunity to elevate your coding skills and master the art of Vim in a contemporary development setting. See you there!

#vim #code #vscode

Vim in VS Code
鈕 筑

鈕 筑

1681292520

Python 的 While 循环中的标志是什么?

在本 Python 教程中,我们了解 Python 的 While 循环中的标志是什么?在 while 循环中使用标志变量在 python 和其他语言中是标准的。它是用于表示何时退出循环的布尔变量的命名法。在本文中,我们将深入探讨此标志的使用以及为什么有必要在 while 循环中使用它。让我们开始吧!

循环

循环用于连续运行特定的代码块。While 循环是一种循环,它循环执行一段代码,直到满足某个条件。While 循环是编程中常用但功能强大的工具。

While 循环的语法

while (condition):
      #code to be looped goes here

while循环可以通过使用关键字'while'然后在同一行中写入条件来使用,该行之后的代码块将循环直到满足条件。缩进标记了 python 循环中的代码。

一个演示 While 循环的简单示例

i = 10 #declaring a variable i with value 10
while i!=0: 
    # looping the code block until the value of i is not equal 0
    print(i)
    i-=1

输出:-

一个简单的 While 循环程序的代码和输出

一个简单的 While 循环程序的代码和输出

首先,我们在上面的例子中设置“i”的值为 10。之后,以 i!= 0 为约束启动 while 循环。即,直到 i 的值不等于 0,解释器将执行代码块。我们打印 i 的值,然后在循环中包含的代码块中每次将其值减 1。结果,解释器重复打印 i 的值,直到 i 的值等于 0,此时它退出循环。

因此,我们为 i 指定的值 10 是打印的第一个值。在打印出 i 的值后,解释器接着读取下一行,即 i-=1。i 的值在此行中设置为 i-1。结果,i 现在的值为 10-1,即 9。解释器现在确定 i 是否为 0。由于 i 的值为 9,解释器继续运行代码块。它现在显示 i (i=9) 的值,然后再次将其设置为 i=i-1 (i = 9-1 = 8)。

当 i 的值最终等于 0 时,解释器暂停运行代码块并再次检查 i 的值是否为 0。无论是与否,它都会不断打印 i 的值并将其减 1 直到它是。

标志变量

标志是用于变量的通用命名法,它采用布尔值并用作特定条件的标记。根据我们如何使用它,它可以在程序的任何地方使用并且非常有用。最常见的是,标志被用作 while 循环条件。当标志的值为 True 时循环将继续,如果变为 False 则循环结束。

让我们检查一个例子,以便更好地理解我们如何使用标志变量,

flag = True # initializing flag with true value
i=10 # initializing i with value 10
# Started a loop with a condition that flag==True
while flag:
    print(i)
    if i==1:
        flag = False # changing the value of flag to False in a way that the loop terminates before printing 0
    else:
        i-=1

输出:-

标志变量示例的代码和输出

while 循环中标志变量示例的代码和输出

在上一个示例中,我们执行了相同的操作,但这次我们使用了一个标志变量。标志的值设置为 True,并以标志作为条件执行 while 循环。直到我们不将标志的值设置为 False,循环将继续执行。

我们现在开始打印 i 的值。如果 i == 1,我们在代码块中设置一个 if 条件以将标志的值修改为 False。因此,下一次解释器尝试迭代循环时,循环终止,因为标志的值现在为 False。这是因为一旦 i 的值变为 1,解释器就会将标志的值更改为 False。

我们可以以不同的方式使用标志变量,比如标记一个我们稍后将在程序中检查的条件。

让我们编写一个程序来使用标志变量检查数字是否为素数,

flag = True # initializing flag with true value
for i in range(2):
    n=int(input("Enter a number:")) # Take a number as input from the user
    # Run a loop on all the numbers smaller than n and check if any of them divides n
    for i in range(n-1,1,-1):
        if n%i==0:
            flag = False
    #check the value of flag and print if the the number is prime or not
    if flag:
        print("The number is prime")
    else:
        print("The number isn't prime")

使用标志检查数字是否为质数的代码和输出

使用标志检查数字是否为质数的代码和输出

在上面的程序中,我们检查了给定的数字是否为素数。首先,我们用 True 值初始化了一个标志变量。然后我们用一个for循环将下面的代码块执行了2次。然后我们运行一个循环,从 i 的值为 n-1 开始,直到 i 的值变为 1 然后跳出循环。现在,接下来的两行代码“if n%i==0”和“flag=False”检查 n 除以 i 后的余数是否为 0。如果是,即 n 可被 n-1 到 2 之间的任何数字整除,则标志的值将设置为 False,标记该数字不是质数。

稍后,我们必须检查标志的值是 True 还是 False,我们可以确定该数是否为素数。

同样,我们可以通过多种方式使用标志;我们只需要知道何时使用它们。只要继续编程,你就会明白我们什么时候可以使用标志而不需要它。

结论

我希望你理解标志变量的意义。它不是那么大,但却是编程的基本概念。作为程序员,我们必须知道如何在不同的条件下利用事物来发挥我们的优势。如果使用得当,标志可以证明非常强大。

文章原文出处:https: //www.askpython.com

#python 

Python 的 While 循环中的标志是什么?

Что такое флаг в цикле while в Python?

В этом руководстве по Python мы узнаем, что такое флаг в цикле While в Python? Использование флаговых переменных в циклах while является стандартным для Python и других языков. Это номенклатура, используемая для логической переменной, которая указывает, когда выйти из цикла. В этой статье мы углубимся в использование этого флага и почему необходимо использовать его в циклах while. Давайте начнем!

Петли

Циклы используются для непрерывного выполнения определенного блока кода. Цикл while — это тип цикла, который перебирает блок кода до тех пор, пока не будет выполнено определенное условие. Цикл while является распространенным, но мощным инструментом в программировании.

Синтаксис цикла while

while (condition):
      #code to be looped goes here

Цикл while можно использовать, используя ключевое слово «пока», а затем записывая условие в той же строке, блок кода, расположенный после этой строки, будет зацикливаться до тех пор, пока условие не будет выполнено. Отступ отмечает код внутри цикла в python.

Простой пример для демонстрации цикла while

i = 10 #declaring a variable i with value 10
while i!=0: 
    # looping the code block until the value of i is not equal 0
    print(i)
    i-=1

Выход:-

Код и вывод для простой программы цикла while

Код и вывод для простой программы цикла while

Во-первых, мы установили «i» в приведенном выше примере равным 10. После этого был инициирован цикл while с ограничением, что i!= 0. т. е. пока значение i не равно 0, интерпретатор выполнит блок кода. Мы печатаем значение i, а затем каждый раз уменьшаем его значение на 1 в блоке кода, содержащемся в цикле. В результате интерпретатор повторяет вывод значения i до тех пор, пока значение i не станет равным 0, после чего он выходит из цикла.

Следовательно, значение, которое мы указываем для i, равное 10, является первым напечатанным значением. Затем интерпретатор читает следующую строку i-=1 после вывода значения i. Значение i устанавливается равным i-1 в этой строке. В результате у меня теперь есть значение 10-1, которое равно 9. Теперь интерпретатор определяет, равен ли я 0 или нет. Интерпретатор возобновляет выполнение блока кода, поскольку значение i равно 9. Теперь он отображает значение i (i=9), прежде чем установить его еще раз на i=i-1 (i = 9-1 = 8).

Когда значение i, наконец, становится равным 0, интерпретатор приостанавливает выполнение блока кода и еще раз проверяет, является ли значение i равным 0. независимо от того, так это или нет, он продолжает печатать значение i и уменьшать его на 1 до тех пор, пока оно не будет получено.

Переменная флага

Флаг — это общая номенклатура, используемая для переменной, которая принимает логическое значение и служит маркером для определенного условия. В зависимости от того, как мы его используем, он может использоваться в любом месте программы и быть весьма полезным. Чаще всего флаг используется как условие цикла while. Цикл будет продолжаться, пока значение флага равно True, и завершится, если оно станет False.

Давайте рассмотрим пример, чтобы лучше понять, как именно мы можем использовать переменную флага,

flag = True # initializing flag with true value
i=10 # initializing i with value 10
# Started a loop with a condition that flag==True
while flag:
    print(i)
    if i==1:
        flag = False # changing the value of flag to False in a way that the loop terminates before printing 0
    else:
        i-=1

Выход:-

Код и вывод для примера для переменной флага

Код и вывод для примера для переменной флага в цикле while

В последнем примере мы выполнили идентичное действие, но на этот раз мы использовали переменную флага. Значение флага было установлено на True, и цикл while выполнялся с флагом, выступающим в качестве условия. Пока мы не установим значение флага в False, цикл будет продолжать выполняться.

Теперь мы начали печатать значение i. Если i == 1, мы устанавливаем условие if в блоке кода, чтобы изменить значение флага на False. Поэтому в следующий раз, когда интерпретатор попытается выполнить итерацию цикла, цикл завершится, так как значение флага теперь равно False. Это связано с тем, что как только значение i изменится на 1, интерпретатор изменит значение флага на False.

Мы можем использовать переменную флага по-разному, например, отметить условие, которое мы проверим позже в программе.

Давайте напишем программу для проверки того, является ли число простым или нет, используя переменную флага,

flag = True # initializing flag with true value
for i in range(2):
    n=int(input("Enter a number:")) # Take a number as input from the user
    # Run a loop on all the numbers smaller than n and check if any of them divides n
    for i in range(n-1,1,-1):
        if n%i==0:
            flag = False
    #check the value of flag and print if the the number is prime or not
    if flag:
        print("The number is prime")
    else:
        print("The number isn't prime")

Код и вывод, чтобы проверить, является ли число простым или не использует флаг

Код и вывод, чтобы проверить, является ли число простым или не использует флаг

В приведенной выше программе мы проверяли, является ли заданное число простым. Во-первых, мы инициализировали переменную флага значением True. Затем мы использовали цикл for для выполнения следующего блока кода 2 раза. Затем мы запустили цикл, начиная со значения i как n-1 до тех пор, пока значение i не станет равным 1, а затем выходим из цикла. Теперь следующие 2 строки кода, «if n%i==0» и «flag=False», проверяют, дает ли n остаток 0 при делении на i. Если это так, т. е. n делится на любое число от n-1 до 2, значение флага будет установлено в False, отмечая, что число не является простым числом.

Позже мы должны проверить, является ли значение флага истинным или ложным, и мы можем определить, является ли число простым или нет.

Точно так же мы можем использовать флаги разными способами; нам просто нужно знать, когда их использовать. Просто продолжайте программировать, и вы поймете, когда мы можем использовать флаг, а когда он не нужен.

Заключение

Надеюсь, вы понимаете значение переменной флага. Это не такое уж большое, но важное понятие программирования. Мы должны знать, как использовать вещи в своих интересах в различных условиях как программисты. Флаги могут оказаться очень мощными, если их правильно использовать.

Оригинальный источник статьи: https://www.askpython.com

#python 

Что такое флаг в цикле while в Python?

Qual é a bandeira no loop while em Python?

Neste tutorial do Python, aprendemos sobre o que é a bandeira no loop while em Python? O uso de variáveis ​​de sinalizador em loops while é padrão em python e em outras linguagens. É uma nomenclatura usada para uma variável booleana que denota quando sair de um loop. Neste artigo, vamos nos aprofundar no uso desse sinalizador e porque é necessário usá-lo em loops while. Vamos começar!

rotações

Os loops são usados ​​para executar continuamente um bloco específico de código. Loop while é um tipo de loop que percorre um bloco de código até que uma determinada condição seja atendida. O loop while é uma ferramenta comum, porém poderosa, na programação.

Sintaxe para loop while

while (condition):
      #code to be looped goes here

Enquanto o loop pode ser usado usando a palavra-chave 'while' e, em seguida, escrevendo a condição na mesma linha, o bloco de código pretendido após esta linha será repetido até que a condição seja atendida. O recuo marca o código dentro do loop em python.

Um exemplo simples para demonstrar o loop while

i = 10 #declaring a variable i with value 10
while i!=0: 
    # looping the code block until the value of i is not equal 0
    print(i)
    i-=1

Saída:-

Código e saída para um programa de loop while simples

Código e saída para um programa de loop while simples

Primeiro, definimos “i” no exemplo acima para ter um valor de 10. Depois disso, um loop while foi iniciado com a restrição de que i!= 0. ou seja, até que o valor de i não seja igual a 0, o interpretador executará o bloco de código. Imprimimos o valor de i e, a cada vez, diminuímos seu valor em 1 no bloco de código contido no loop. Como resultado, o interpretador repete a impressão do valor de i até que o valor de i seja igual a 0, ponto em que ele sai do loop.

Conseqüentemente, o valor que especificamos para i, que é 10, é o primeiro valor impresso. O interpretador então lê a próxima linha, que é i-=1, depois de imprimir o valor de i. O valor de i é definido como i-1 nesta linha. Como resultado, agora tenho um valor de 10-1, que é 9. O interpretador agora determina se i=0 ou não. O interpretador retoma a execução do bloco de código, pois o valor de i é 9. Ele agora exibe o valor de i (i=9) antes de defini-lo mais uma vez como i=i-1 (i = 9-1 = 8).

Quando o valor de i finalmente for igual a 0, o interpretador pausa a execução do bloco de código e verifica mais uma vez se o valor de i=0. seja ou não, ele continua imprimindo o valor de i e reduzindo em 1 até que seja.

Variável de sinalização

Um sinalizador é uma nomenclatura comum usada para uma variável que assume um valor booleano e serve como um marcador para uma condição específica. Dependendo de como o utilizamos, ele pode ser usado em qualquer lugar do programa e ser bastante útil. Mais frequentemente, um sinalizador é empregado como uma condição de loop while. O loop continuaria enquanto o valor do sinalizador fosse True e terminaria se ele se tornasse False.

Vamos ver um exemplo dela para entender melhor como exatamente podemos usar a variável flag,

flag = True # initializing flag with true value
i=10 # initializing i with value 10
# Started a loop with a condition that flag==True
while flag:
    print(i)
    if i==1:
        flag = False # changing the value of flag to False in a way that the loop terminates before printing 0
    else:
        i-=1

Saída:-

Código e saída para um exemplo de variável de sinalizador

Código e saída para um exemplo de variável de sinalizador no loop while

No último exemplo, realizamos a ação idêntica, mas desta vez usamos uma variável de sinalizador. O valor do sinalizador foi definido como True e o loop while foi executado com o sinalizador servindo como condição. Até que não definamos o valor do sinalizador como False, o loop continuará a ser executado.

Agora começamos a imprimir o valor de i. Se i == 1, definimos uma condição if no bloco de código para modificar o valor do sinalizador para Falso. Portanto, na próxima vez que o interpretador tentar iterar no loop, o loop terminará quando o valor do sinalizador for False agora. Isso ocorre porque assim que o valor de i mudar para 1, o interpretador alterará o valor do sinalizador para Falso.

Podemos usar a variável flag de diversas formas, como marcar uma condição que iremos verificar posteriormente no programa.

Vamos escrever um programa para verificar se um número é primo ou não usando uma variável de sinalizador,

flag = True # initializing flag with true value
for i in range(2):
    n=int(input("Enter a number:")) # Take a number as input from the user
    # Run a loop on all the numbers smaller than n and check if any of them divides n
    for i in range(n-1,1,-1):
        if n%i==0:
            flag = False
    #check the value of flag and print if the the number is prime or not
    if flag:
        print("The number is prime")
    else:
        print("The number isn't prime")

Código e saída para verificar se um número é primo ou não usando sinalizador

Código e saída para verificar se um número é primo ou não usando sinalizador

No programa acima, verificamos se um determinado número é primo. Primeiro, inicializamos uma variável flag com o valor True. Em seguida, usamos um loop for para executar o seguinte bloco de código 2 vezes. Em seguida, executamos um loop, começando com o valor de i como n-1 até que o valor de i se torne 1 e, em seguida, saindo do loop. Agora as próximas 2 linhas de código, “if n%i==0” e “flag=False”, verifique se n dá resto 0 quando dividido por i. Se for, ou seja, n é divisível por qualquer número de n-1 a 2, o valor do sinalizador será definido como False, marcando que o número não é um número primo.

Posteriormente, temos que verificar se o valor do sinalizador é True ou False, e podemos determinar se o número é primo ou não.

Da mesma forma, podemos usar sinalizadores de várias maneiras; só precisamos saber quando usá-los. Continue programando e você entenderá quando podemos usar o sinalizador e não precisamos dele.

Conclusão

Espero que você entenda o significado da variável flag. Não é tão grande, mas um conceito essencial de programação. Devemos saber usar as coisas a nosso favor em diferentes condições como programadores. Os sinalizadores podem ser muito poderosos se usados ​​corretamente.

Fonte do artigo original em: https://www.askpython.com

#python 

Qual é a bandeira no loop while em Python?
Hoang  Kim

Hoang Kim

1681223113

Cờ trong vòng lặp While trong Python là gì?

Trong hướng dẫn Python này, chúng ta tìm hiểu về Cờ trong Vòng lặp While trong Python là gì? Sử dụng biến cờ trong vòng lặp while là tiêu chuẩn trong python và các ngôn ngữ khác. Đó là một danh pháp được sử dụng cho một biến boolean biểu thị thời điểm thoát khỏi vòng lặp. Trong bài viết này, chúng ta sẽ tìm hiểu sâu về cách sử dụng cờ này và lý do tại sao cần sử dụng nó trong vòng lặp while. Bắt đầu nào!

vòng lặp

Các vòng lặp được sử dụng để chạy liên tục một khối mã cụ thể. Vòng lặp While là loại vòng lặp lặp qua một khối mã lệnh cho đến khi thỏa mãn một điều kiện nào đó. Vòng lặp While là một công cụ phổ biến nhưng mạnh mẽ trong lập trình.

Cú pháp vòng lặp While

while (condition):
      #code to be looped goes here

Vòng lặp while có thể được sử dụng bằng cách sử dụng từ khóa 'while' và sau đó viết điều kiện trên cùng một dòng, khối mã dự định sau dòng này sẽ được lặp lại cho đến khi điều kiện được đáp ứng. Dấu đầu dòng đánh dấu mã bên trong vòng lặp trong python.

Một ví dụ đơn giản để chứng minh vòng lặp While

i = 10 #declaring a variable i with value 10
while i!=0: 
    # looping the code block until the value of i is not equal 0
    print(i)
    i-=1

Đầu ra: -

Mã và đầu ra cho một chương trình vòng lặp đơn giản

Mã và đầu ra cho một chương trình vòng lặp đơn giản

Đầu tiên, chúng tôi đặt “i” trong ví dụ trên có giá trị là 10. Sau đó, một vòng lặp while được bắt đầu với ràng buộc i!= 0. tức là cho đến khi giá trị của i khác 0, trình thông dịch sẽ thực thi khối mã. Chúng tôi in giá trị của i và sau đó mỗi lần giảm giá trị của nó đi 1 trong khối mã có trong vòng lặp. Kết quả là, trình thông dịch lặp lại việc in giá trị của i cho đến khi giá trị của i bằng 0, lúc đó nó sẽ thoát khỏi vòng lặp.

Do đó, giá trị chúng tôi chỉ định cho i, là 10, là giá trị đầu tiên được in. Trình thông dịch sau đó đọc dòng tiếp theo, i-=1, sau khi in giá trị của i. Giá trị của i được đặt thành i-1 trong dòng này. Kết quả là, bây giờ i có giá trị 10-1 là 9. Trình thông dịch hiện xác định xem i=0 hay không. Trình thông dịch tiếp tục chạy khối mã vì giá trị của i là 9. Bây giờ nó hiển thị giá trị của i (i=9) trước khi đặt nó một lần nữa thành i=i-1 (i = 9-1 = 8).

Khi giá trị của i cuối cùng bằng 0, trình thông dịch tạm dừng chạy khối mã và kiểm tra lại một lần nữa để xem liệu giá trị của i có = 0 hay không. dù có hay không, nó vẫn tiếp tục in giá trị của i và giảm nó đi 1 cho đến khi đạt được.

Biến cờ

Cờ là một danh pháp phổ biến được sử dụng cho một biến nhận giá trị boolean và đóng vai trò là điểm đánh dấu cho một điều kiện cụ thể. Tùy thuộc vào cách chúng tôi sử dụng nó, nó có thể được sử dụng ở bất kỳ đâu trong chương trình và khá hữu ích. Thường xuyên nhất, một lá cờ được sử dụng như một điều kiện của vòng lặp while. Vòng lặp sẽ tiếp tục trong khi giá trị của cờ là Đúng và kết thúc nếu nó trở thành Sai.

Hãy xem một ví dụ về nó để hiểu rõ hơn về cách chính xác chúng ta có thể sử dụng biến cờ,

flag = True # initializing flag with true value
i=10 # initializing i with value 10
# Started a loop with a condition that flag==True
while flag:
    print(i)
    if i==1:
        flag = False # changing the value of flag to False in a way that the loop terminates before printing 0
    else:
        i-=1

Đầu ra: -

Mã và đầu ra cho một ví dụ cho biến cờ

Mã và đầu ra cho một ví dụ cho biến cờ trong vòng lặp while

Trong ví dụ trước, chúng tôi đã thực hiện cùng một hành động, nhưng lần này chúng tôi đã sử dụng một biến cờ. Giá trị của cờ được đặt thành True và vòng lặp while được thực thi với cờ đóng vai trò là điều kiện. Cho đến khi chúng tôi không đặt giá trị của cờ thành Sai, vòng lặp sẽ tiếp tục thực thi.

Bây giờ chúng tôi bắt đầu in giá trị của tôi. Nếu i == 1, chúng tôi đặt điều kiện if trong khối mã để sửa đổi giá trị của cờ thành Sai. Do đó, lần tiếp theo trình thông dịch cố gắng lặp lại vòng lặp, vòng lặp sẽ kết thúc vì giá trị của cờ hiện là Sai. Điều này là do ngay khi giá trị của i thay đổi thành 1, trình thông dịch sẽ thay đổi giá trị của cờ thành Sai.

Chúng ta có thể sử dụng biến cờ theo nhiều cách khác nhau, chẳng hạn như đánh dấu một điều kiện mà chúng ta sẽ kiểm tra sau trong chương trình.

Hãy viết chương trình kiểm tra một số có phải là số nguyên tố hay không bằng biến cờ,

flag = True # initializing flag with true value
for i in range(2):
    n=int(input("Enter a number:")) # Take a number as input from the user
    # Run a loop on all the numbers smaller than n and check if any of them divides n
    for i in range(n-1,1,-1):
        if n%i==0:
            flag = False
    #check the value of flag and print if the the number is prime or not
    if flag:
        print("The number is prime")
    else:
        print("The number isn't prime")

Mã và đầu ra để kiểm tra xem một số có phải là số nguyên tố hay không bằng cách sử dụng cờ

Mã và đầu ra để kiểm tra xem một số có phải là số nguyên tố hay không bằng cách sử dụng cờ

Trong chương trình trên, chúng tôi đã kiểm tra xem một số đã cho có phải là số nguyên tố hay không. Đầu tiên, chúng tôi đã khởi tạo một biến cờ với giá trị True. Sau đó, chúng tôi đã sử dụng vòng lặp for để thực hiện khối mã sau 2 lần. Sau đó, chúng tôi chạy một vòng lặp, bắt đầu với giá trị của i là n-1 cho đến khi giá trị của i trở thành 1 rồi thoát ra khỏi vòng lặp. Bây giờ, 2 dòng mã tiếp theo, “if n%i==0” và “flag=False”, hãy kiểm tra xem n có cho số dư 0 khi chia cho i hay không. Nếu đúng như vậy, tức là n chia hết cho bất kỳ số nào từ n-1 đến 2, giá trị của cờ sẽ được đặt thành Sai, đánh dấu rằng số đó không phải là số nguyên tố.

Sau đó, chúng tôi phải kiểm tra xem giá trị của cờ là Đúng hay Sai và chúng tôi có thể xác định xem số đó có phải là số nguyên tố hay không.

Tương tự, chúng ta có thể sử dụng cờ theo nhiều cách; chúng ta chỉ cần biết khi nào nên sử dụng chúng. Chỉ cần tiếp tục lập trình và bạn sẽ hiểu khi nào chúng ta có thể sử dụng cờ và không cần nó.

Phần kết luận

Tôi hy vọng bạn hiểu ý nghĩa của biến cờ. Nó không lớn lắm, nhưng là một khái niệm thiết yếu của lập trình. Chúng ta phải biết cách sử dụng mọi thứ có lợi cho mình trong các điều kiện khác nhau với tư cách là lập trình viên. Cờ có thể được chứng minh là rất mạnh nếu được sử dụng đúng cách.

Nguồn bài viết gốc tại: https://www.askpython.com

#python 

Cờ trong vòng lặp While trong Python là gì?
Layne  Fadel

Layne Fadel

1681148340

What Is The Flag in The While Loop In Python?

In this Python tutorial we learn about What Is The Flag in The While Loop In Python? Using flag variables in while loops are standard in python and other languages. It’s a nomenclature used for a boolean variable that denotes when to get out of a loop. In this article, we’ll be getting deep into the use of this flag and why it is necessary to use it in while loops. Let’s get started!

Loops

Loops are used to continually run a specific block of code. While loop is a type of loop that loops through a block of code until a certain condition is met. While loop is a common yet powerful tool in programming.

Syntax For While Loop

while (condition):
      #code to be looped goes here

While loop can be used by using the keyword ‘while’ and then writing the condition in the same line, the code block intended after this line will be looped until the condition is met. The indentation marks the code inside the loop in python.

A Simple Example To Demonstrate While Loop

i = 10 #declaring a variable i with value 10
while i!=0: 
    # looping the code block until the value of i is not equal 0
    print(i)
    i-=1

Output:-

Code And Output For A Simple While Loop Program

Code And Output For A Simple While Loop Program

First, we set “i” in the example above to have a value of 10. After that, a while loop was initiated with the constraint that i!= 0. i.e., until the value of i is not equal to 0, the interpreter will execute the block of code. We print the value of i and then each time decrease its value by 1 in the code block contained within the loop. As a result, the interpreter repeats printing the value of i until the value of i equals 0, at which point it exits the loop.

Consequently, the value we specify for i, which is 10, is the first value printed. The interpreter then reads the next line, which is i-=1, after printing the value of i. The value of i is set to i-1 in this line. As a result, i now have a value of 10-1 which is 9. The interpreter now determines if i=0 or not. The interpreter resumes running the code block since the value of i is 9. It now displays the value of i (i=9) before setting it once more to i=i-1 (i = 9-1 = 8).

When the value of i finally equals 0, the interpreter pauses running the code block and checks once more to see whether the value of i=0. whether it is or not, it keeps printing the value of i and reducing it by 1 until it is.

Flag variable

A flag is a common nomenclature used for a variable that takes a boolean value and serves as a marker for a specific condition. Depending on how we utilize it, it can be used anywhere in the program and be quite helpful. Most frequently, a flag is employed as a while loop condition. The loop would continue while the flag’s value was True and end if it became False.

Let’s check an example of it to have a better understanding of how exactly we can use the flag variable,

flag = True # initializing flag with true value
i=10 # initializing i with value 10
# Started a loop with a condition that flag==True
while flag:
    print(i)
    if i==1:
        flag = False # changing the value of flag to False in a way that the loop terminates before printing 0
    else:
        i-=1

Output:-

Code And Output For An Example For Flag Variable

Code And Output For An Example For Flag Variable in while loop

In the last example, we carried out the identical action, but this time we used a flag variable. The flag’s value was set to True, and the while loop was executed with the flag serving as the condition. Till we don’t set the flag’s value to False, the loop will continue to execute.

We now began printing i’s value. If i == 1, we set an if condition in the code block to modify the flag’s value to False. Therefore, the next time the interpreter tries to iterate over the loop, the loop terminates as the value of the flag is False now. This is because as soon as the value of i changes to 1, the interpreter will alter the value of the flag to False.

We can use the flag variable in different ways, like marking a condition we will check later in the program.

Let’s write a program to check if a number is prime or not using a flag variable,

flag = True # initializing flag with true value
for i in range(2):
    n=int(input("Enter a number:")) # Take a number as input from the user
    # Run a loop on all the numbers smaller than n and check if any of them divides n
    for i in range(n-1,1,-1):
        if n%i==0:
            flag = False
    #check the value of flag and print if the the number is prime or not
    if flag:
        print("The number is prime")
    else:
        print("The number isn't prime")

Code And Output To Check If A Number Is Prime Or Not Using Flag

Code And Output To Check If A Number Is Prime Or Not Using Flag

In the above program, we checked whether a given number is prime. First, we initialized a flag variable with the True value. Then we used a for loop to perform the following code block 2 times. Then we ran a loop, starting with the value of i as n-1 till the value of i becomes 1 and then breaking out of the loop. Now the next 2 lines of code, “if n%i==0” and “flag=False,” check if n gives remainder 0 when divided by i. If it does, i.e., n is divisible by any number from n-1 to 2, the flag’s value will be set to False, marking that the number is not a prime number.

Later, we have to check if the flag’s value is True or False, and we can determine if the number is prime or not.

Similarly, we can use flags in many ways; we just need to know when to use them. Just keep programming, and you’ll understand when we can use the flag and don’t need it.

Conclusion

I hope you understand the significance of the flag variable. It’s not that big, but an essential concept of programming. We must know how to use things to our advantage in different conditions as programmers. Flags can be proven very powerful if used properly.

Original article source at: https://www.askpython.com

#python 

What Is The Flag in The While Loop In Python?