Annie  Emard

Annie Emard

1652660940

Check That Your Puppet Manifests Conform to The Style Guide

Puppet Lint

Note that as of release 2.5.0, this project is being maintained in the main puppetlabs namespace.

Puppet Lint tests Puppet code against the recommended Puppet language style guide. Puppet Lint validates only code style; it does not validate syntax. To test syntax, use Puppet's puppet parser validate command.

Compatibility warning

Puppet Lint version 2 is the last planned version with support for Puppet 3 and Ruby 1.8.7. The next major version of Puppet Lint will drop support for these versions.

Installation

Install the Puppet Lint gem by running:

gem install puppet-lint

Testing with Puppet Lint

To test manifests for correct Puppet style, run the puppet-lint command with the path to the files you want to test.

For example:

puppet-lint ~/modules/puppetlabs-java/manifests/init.pp
puppet-lint ~/modules/puppetlabs-mysql/manifests

Fix issues automatically

To instruct Lint to automatically fix any issues that it detects, use the --fix flag:

puppet-lint --fix /modules

Modify which checks to run

Puppet Lint options allow you to modify which checks to run. You can disable any of the checks temporarily or permanently, or you can limit testing to specific checks.

List all available checks

To list all available checks along with basic usage documentation, use the --list-checks option.

Run specific checks

To run only specific checks, use the --only-checks option, with a comma-separated list of arguments specifying which checks to make:

puppet-lint --only-checks trailing_whitespace,140chars modules/

To avoid enormous patch sets when using the --fix flag, use the --only-checks option to limit which checks Puppet Lint makes:

puppet-lint --only-checks trailing_whitespace --fix modules/

Disable Lint checks

You can disable specific Lint checks on the command line, disable them permanently with a configuration file, or disable them with control comments within your Puppet code.

Disable checks on the command line

To disable any of the checks when running the puppet-lint command, add a --no-<check_name>-check flag to the command. For example, to skip the 140-character check, run:

puppet-lint --no-140chars-check modules/

Disable checks within Puppet code

To disable checks from within your Puppet code itself, use control comments. Disable checks on either a per-line or per-block basis using #lint:ignore:<check_name>.

For example:

class foo {
  $bar = 'bar'

  # This ignores the double_quoted_strings check over multiple lines

  # lint:ignore:double_quoted_strings
  $baz = "baz"
  $gronk = "gronk"
  # lint:endignore

  # This ignores the 140chars check on a single line

  $this_line_has_a_really_long_name_and_value_that_is_much_longer_than_the_style_guide_recommends = "I mean, a really, really long line like you can't believe" # lint:ignore:140chars
}

Configuration file

Each time Puppet Lint starts up, it loads configuration from three files in order:

  1. /etc/puppet-lint.rc
  2. ~/.puppet-lint.rc
  3. .puppet-lint.rc

This means that a flag in the local .puppet-lint.rc will take precedence over a flag in the global /etc/puppet-lint.rc, for example. Flags specified on the command line take final precedence and override all config file options.

Any flag that can be specified on the command line can also be specified in the configuration file. For example, to always skip the hard tab character check, create ~/.puppet-lint.rc and include the line:

--no-hard_tabs-check

Or to specify a whitelist of allowed checks, include a line like:

--only-checks=trailing_whitespace,hard_tabs,duplicate_params,double_quoted_strings,unquoted_file_mode,only_variable_string,variables_not_enclosed,single_quote_string_with_variables,variable_contains_dash,ensure_not_symlink_target,unquoted_resource_title,relative_classname_inclusion,file_mode,resource_reference_without_title_capital,leading_zero,arrow_alignment,variable_is_lowercase,ensure_first_param,resource_reference_without_whitespace,file_ensure,trailing_comma,leading_zero

Please note that there is an important difference between reading options from the command line and reading options from a configuration file: In the former case the shell interprets one level of quotes. That does not happen in the latter case. So, it would make sense to quote some configuration values on the command line, like so:

$ puppet-lint --ignore-paths 'modules/stdlib/*' modules/

When reading from a configuration file those quotes would be passed on to the option parser -- probably not giving the expected result. Instead the line should read

--ignore-paths=modules/stdlib/*

Testing with Puppet Lint as a Rake task

To test your entire Puppet manifest directory, add require 'puppet-lint/tasks/puppet-lint' to your Rakefile and then run:

rake lint

To modify the default behaviour of the Rake task, modify the Puppet Lint configuration by defining the task yourself. For example:

PuppetLint::RakeTask.new :lint do |config|  # Pattern of files to check, defaults to `**/*.pp`  config.pattern = 'modules'  # Pattern of files to ignore  config.ignore_paths = ['modules/apt', 'modules/stdlib']  # List of checks to disable  config.disable_checks = ['documentation', '140chars']  # Should puppet-lint prefix it's output with the file being checked,  # defaults to true  config.with_filename = false  # Should the task fail if there were any warnings, defaults to false  config.fail_on_warnings = true  # Format string for puppet-lint's output (see the puppet-lint help output  # for details  config.log_format = '%{filename} - %{message}'  # Print out the context for the problem, defaults to false  config.with_context = true  # Enable automatic fixing of problems, defaults to false  config.fix = true  # Show ignored problems in the output, defaults to false  config.show_ignored = true  # Compare module layout relative to the module root  config.relative = true end

Disable checks in the Lint Rake task

You can also disable checks when running Puppet Lint through the supplied Rake task by modifying your Rakefile.

To disable a check, add the following line after the require statement in your Rakefile:

PuppetLint.configuration.send("disable_<check name>")

For example, to disable the 140-character check, add:

PuppetLint.configuration.send("disable_140chars")

To set the Lint Rake task to ignore certain paths:

PuppetLint.configuration.ignore_paths = ["vendor/**/*.pp"]

To set a pattern of files that Lint should check:

# Defaults to `**/*.pp`
PuppetLint.configuration.pattern = "modules"

Testing with Puppet Lint as a GitHub Action

There is a GitHub Actions action available to get linter feedback in workflows:

Options

See puppet-lint --help for a full list of command line options and checks.

Checks

For a complete list of checks, and how to resolve errors on each check, see the Puppet Lint checks page.

Spacing, Indentation, and Whitespace

  • Must use two-space soft tabs.
  • Must not use literal tab characters.
  • Must not contain trailing white space.
  • Should not exceed an 140-character line width.
    • An exception has been made for source => 'puppet://...' lines as splitting these over multiple lines decreases the readability of the manifests.
  • Should align arrows (=>) within blocks of attributes.

Quoting

  • All strings that do not contain variables should be enclosed in single quotes.
    • An exception has been made for double-quoted strings containing \n or \t.
  • All strings that contain variables must be enclosed in double quotes.
  • All variables should be enclosed in braces when interpolated in a string.
  • Variables standing by themselves should not be quoted.

Capitalization

  • All variables should be in lowercase.

Resources

  • All resource titles should be quoted.
    • An exception has been made for resource titles that consist of only a variable standing by itself.
  • If a resource declaration includes an ensure attribute, it should be the first attribute specified.
  • Symbolic links should be declared by using an ensure value of link and explicitly specifying a value for the target attribute.
  • File modes should be represented as a 4-digit string enclosed in single quotes or use symbolic file modes.

Conditionals

  • You should not intermingle conditionals inside resource declarations (that is, selectors inside resources).
  • Case statements should have a default case.

Classes

  • Relationship declarations with the chaining syntax should only be used in the 'left to right' direction.
  • Classes should not be defined inside a class.
  • Defines should not be defined inside a class.
  • Classes should not inherit between namespaces.
  • Required parameters in class & defined type definitions should be listed before optional parameters.
  • When using top-scope variables, including facts, Puppet modules should explicitly specify the empty namespace.
  • Chaining operators should appear on the same line as the right hand operand.

Reporting bugs or incorrect results

If you find a bug in Puppet Lint or its results, please create an issue in the repo issues tracker. Bonus points will be awarded if you also include a patch that fixes the issue.

Thank you

Many thanks to the following people for contributing to puppet-lint

  • James Turnbull (@kartar)
  • Jan Vansteenkiste (@vStone)
  • Julian Simpson (@simpsonjulian)
  • S. Zachariah Sprackett (@zsprackett)

As well as the many people who have reported the issues they've had!

License

Copyright (c) 2011-2016 Tim Sharpe

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author: rodjek
Source Code: https://github.com/rodjek/puppet-lint
License: MIT License

#puppet #lint 

What is GEEK

Buddha Community

Check That Your Puppet Manifests Conform to The Style Guide
Annie  Emard

Annie Emard

1652660940

Check That Your Puppet Manifests Conform to The Style Guide

Puppet Lint

Note that as of release 2.5.0, this project is being maintained in the main puppetlabs namespace.

Puppet Lint tests Puppet code against the recommended Puppet language style guide. Puppet Lint validates only code style; it does not validate syntax. To test syntax, use Puppet's puppet parser validate command.

Compatibility warning

Puppet Lint version 2 is the last planned version with support for Puppet 3 and Ruby 1.8.7. The next major version of Puppet Lint will drop support for these versions.

Installation

Install the Puppet Lint gem by running:

gem install puppet-lint

Testing with Puppet Lint

To test manifests for correct Puppet style, run the puppet-lint command with the path to the files you want to test.

For example:

puppet-lint ~/modules/puppetlabs-java/manifests/init.pp
puppet-lint ~/modules/puppetlabs-mysql/manifests

Fix issues automatically

To instruct Lint to automatically fix any issues that it detects, use the --fix flag:

puppet-lint --fix /modules

Modify which checks to run

Puppet Lint options allow you to modify which checks to run. You can disable any of the checks temporarily or permanently, or you can limit testing to specific checks.

List all available checks

To list all available checks along with basic usage documentation, use the --list-checks option.

Run specific checks

To run only specific checks, use the --only-checks option, with a comma-separated list of arguments specifying which checks to make:

puppet-lint --only-checks trailing_whitespace,140chars modules/

To avoid enormous patch sets when using the --fix flag, use the --only-checks option to limit which checks Puppet Lint makes:

puppet-lint --only-checks trailing_whitespace --fix modules/

Disable Lint checks

You can disable specific Lint checks on the command line, disable them permanently with a configuration file, or disable them with control comments within your Puppet code.

Disable checks on the command line

To disable any of the checks when running the puppet-lint command, add a --no-<check_name>-check flag to the command. For example, to skip the 140-character check, run:

puppet-lint --no-140chars-check modules/

Disable checks within Puppet code

To disable checks from within your Puppet code itself, use control comments. Disable checks on either a per-line or per-block basis using #lint:ignore:<check_name>.

For example:

class foo {
  $bar = 'bar'

  # This ignores the double_quoted_strings check over multiple lines

  # lint:ignore:double_quoted_strings
  $baz = "baz"
  $gronk = "gronk"
  # lint:endignore

  # This ignores the 140chars check on a single line

  $this_line_has_a_really_long_name_and_value_that_is_much_longer_than_the_style_guide_recommends = "I mean, a really, really long line like you can't believe" # lint:ignore:140chars
}

Configuration file

Each time Puppet Lint starts up, it loads configuration from three files in order:

  1. /etc/puppet-lint.rc
  2. ~/.puppet-lint.rc
  3. .puppet-lint.rc

This means that a flag in the local .puppet-lint.rc will take precedence over a flag in the global /etc/puppet-lint.rc, for example. Flags specified on the command line take final precedence and override all config file options.

Any flag that can be specified on the command line can also be specified in the configuration file. For example, to always skip the hard tab character check, create ~/.puppet-lint.rc and include the line:

--no-hard_tabs-check

Or to specify a whitelist of allowed checks, include a line like:

--only-checks=trailing_whitespace,hard_tabs,duplicate_params,double_quoted_strings,unquoted_file_mode,only_variable_string,variables_not_enclosed,single_quote_string_with_variables,variable_contains_dash,ensure_not_symlink_target,unquoted_resource_title,relative_classname_inclusion,file_mode,resource_reference_without_title_capital,leading_zero,arrow_alignment,variable_is_lowercase,ensure_first_param,resource_reference_without_whitespace,file_ensure,trailing_comma,leading_zero

Please note that there is an important difference between reading options from the command line and reading options from a configuration file: In the former case the shell interprets one level of quotes. That does not happen in the latter case. So, it would make sense to quote some configuration values on the command line, like so:

$ puppet-lint --ignore-paths 'modules/stdlib/*' modules/

When reading from a configuration file those quotes would be passed on to the option parser -- probably not giving the expected result. Instead the line should read

--ignore-paths=modules/stdlib/*

Testing with Puppet Lint as a Rake task

To test your entire Puppet manifest directory, add require 'puppet-lint/tasks/puppet-lint' to your Rakefile and then run:

rake lint

To modify the default behaviour of the Rake task, modify the Puppet Lint configuration by defining the task yourself. For example:

PuppetLint::RakeTask.new :lint do |config|  # Pattern of files to check, defaults to `**/*.pp`  config.pattern = 'modules'  # Pattern of files to ignore  config.ignore_paths = ['modules/apt', 'modules/stdlib']  # List of checks to disable  config.disable_checks = ['documentation', '140chars']  # Should puppet-lint prefix it's output with the file being checked,  # defaults to true  config.with_filename = false  # Should the task fail if there were any warnings, defaults to false  config.fail_on_warnings = true  # Format string for puppet-lint's output (see the puppet-lint help output  # for details  config.log_format = '%{filename} - %{message}'  # Print out the context for the problem, defaults to false  config.with_context = true  # Enable automatic fixing of problems, defaults to false  config.fix = true  # Show ignored problems in the output, defaults to false  config.show_ignored = true  # Compare module layout relative to the module root  config.relative = true end

Disable checks in the Lint Rake task

You can also disable checks when running Puppet Lint through the supplied Rake task by modifying your Rakefile.

To disable a check, add the following line after the require statement in your Rakefile:

PuppetLint.configuration.send("disable_<check name>")

For example, to disable the 140-character check, add:

PuppetLint.configuration.send("disable_140chars")

To set the Lint Rake task to ignore certain paths:

PuppetLint.configuration.ignore_paths = ["vendor/**/*.pp"]

To set a pattern of files that Lint should check:

# Defaults to `**/*.pp`
PuppetLint.configuration.pattern = "modules"

Testing with Puppet Lint as a GitHub Action

There is a GitHub Actions action available to get linter feedback in workflows:

Options

See puppet-lint --help for a full list of command line options and checks.

Checks

For a complete list of checks, and how to resolve errors on each check, see the Puppet Lint checks page.

Spacing, Indentation, and Whitespace

  • Must use two-space soft tabs.
  • Must not use literal tab characters.
  • Must not contain trailing white space.
  • Should not exceed an 140-character line width.
    • An exception has been made for source => 'puppet://...' lines as splitting these over multiple lines decreases the readability of the manifests.
  • Should align arrows (=>) within blocks of attributes.

Quoting

  • All strings that do not contain variables should be enclosed in single quotes.
    • An exception has been made for double-quoted strings containing \n or \t.
  • All strings that contain variables must be enclosed in double quotes.
  • All variables should be enclosed in braces when interpolated in a string.
  • Variables standing by themselves should not be quoted.

Capitalization

  • All variables should be in lowercase.

Resources

  • All resource titles should be quoted.
    • An exception has been made for resource titles that consist of only a variable standing by itself.
  • If a resource declaration includes an ensure attribute, it should be the first attribute specified.
  • Symbolic links should be declared by using an ensure value of link and explicitly specifying a value for the target attribute.
  • File modes should be represented as a 4-digit string enclosed in single quotes or use symbolic file modes.

Conditionals

  • You should not intermingle conditionals inside resource declarations (that is, selectors inside resources).
  • Case statements should have a default case.

Classes

  • Relationship declarations with the chaining syntax should only be used in the 'left to right' direction.
  • Classes should not be defined inside a class.
  • Defines should not be defined inside a class.
  • Classes should not inherit between namespaces.
  • Required parameters in class & defined type definitions should be listed before optional parameters.
  • When using top-scope variables, including facts, Puppet modules should explicitly specify the empty namespace.
  • Chaining operators should appear on the same line as the right hand operand.

Reporting bugs or incorrect results

If you find a bug in Puppet Lint or its results, please create an issue in the repo issues tracker. Bonus points will be awarded if you also include a patch that fixes the issue.

Thank you

Many thanks to the following people for contributing to puppet-lint

  • James Turnbull (@kartar)
  • Jan Vansteenkiste (@vStone)
  • Julian Simpson (@simpsonjulian)
  • S. Zachariah Sprackett (@zsprackett)

As well as the many people who have reported the issues they've had!

License

Copyright (c) 2011-2016 Tim Sharpe

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author: rodjek
Source Code: https://github.com/rodjek/puppet-lint
License: MIT License

#puppet #lint 

Shubham Ankit

Shubham Ankit

1657081614

How to Automate Excel with Python | Python Excel Tutorial (OpenPyXL)

How to Automate Excel with Python

In this article, We will show how we can use python to automate Excel . A useful Python library is Openpyxl which we will learn to do Excel Automation

What is OPENPYXL

Openpyxl is a Python library that is used to read from an Excel file or write to an Excel file. Data scientists use Openpyxl for data analysis, data copying, data mining, drawing charts, styling sheets, adding formulas, and more.

Workbook: A spreadsheet is represented as a workbook in openpyxl. A workbook consists of one or more sheets.

Sheet: A sheet is a single page composed of cells for organizing data.

Cell: The intersection of a row and a column is called a cell. Usually represented by A1, B5, etc.

Row: A row is a horizontal line represented by a number (1,2, etc.).

Column: A column is a vertical line represented by a capital letter (A, B, etc.).

Openpyxl can be installed using the pip command and it is recommended to install it in a virtual environment.

pip install openpyxl

CREATE A NEW WORKBOOK

We start by creating a new spreadsheet, which is called a workbook in Openpyxl. We import the workbook module from Openpyxl and use the function Workbook() which creates a new workbook.

from openpyxl
import Workbook
#creates a new workbook
wb = Workbook()
#Gets the first active worksheet
ws = wb.active
#creating new worksheets by using the create_sheet method

ws1 = wb.create_sheet("sheet1", 0) #inserts at first position
ws2 = wb.create_sheet("sheet2") #inserts at last position
ws3 = wb.create_sheet("sheet3", -1) #inserts at penultimate position

#Renaming the sheet
ws.title = "Example"

#save the workbook
wb.save(filename = "example.xlsx")

READING DATA FROM WORKBOOK

We load the file using the function load_Workbook() which takes the filename as an argument. The file must be saved in the same working directory.

#loading a workbook
wb = openpyxl.load_workbook("example.xlsx")

 

GETTING SHEETS FROM THE LOADED WORKBOOK

 

#getting sheet names
wb.sheetnames
result = ['sheet1', 'Sheet', 'sheet3', 'sheet2']

#getting a particular sheet
sheet1 = wb["sheet2"]

#getting sheet title
sheet1.title
result = 'sheet2'

#Getting the active sheet
sheetactive = wb.active
result = 'sheet1'

 

ACCESSING CELLS AND CELL VALUES

 

#get a cell from the sheet
sheet1["A1"] <
  Cell 'Sheet1'.A1 >

  #get the cell value
ws["A1"].value 'Segment'

#accessing cell using row and column and assigning a value
d = ws.cell(row = 4, column = 2, value = 10)
d.value
10

 

ITERATING THROUGH ROWS AND COLUMNS

 

#looping through each row and column
for x in range(1, 5):
  for y in range(1, 5):
  print(x, y, ws.cell(row = x, column = y)
    .value)

#getting the highest row number
ws.max_row
701

#getting the highest column number
ws.max_column
19

There are two functions for iterating through rows and columns.

Iter_rows() => returns the rows
Iter_cols() => returns the columns {
  min_row = 4, max_row = 5, min_col = 2, max_col = 5
} => This can be used to set the boundaries
for any iteration.

Example:

#iterating rows
for row in ws.iter_rows(min_row = 2, max_col = 3, max_row = 3):
  for cell in row:
  print(cell) <
  Cell 'Sheet1'.A2 >
  <
  Cell 'Sheet1'.B2 >
  <
  Cell 'Sheet1'.C2 >
  <
  Cell 'Sheet1'.A3 >
  <
  Cell 'Sheet1'.B3 >
  <
  Cell 'Sheet1'.C3 >

  #iterating columns
for col in ws.iter_cols(min_row = 2, max_col = 3, max_row = 3):
  for cell in col:
  print(cell) <
  Cell 'Sheet1'.A2 >
  <
  Cell 'Sheet1'.A3 >
  <
  Cell 'Sheet1'.B2 >
  <
  Cell 'Sheet1'.B3 >
  <
  Cell 'Sheet1'.C2 >
  <
  Cell 'Sheet1'.C3 >

To get all the rows of the worksheet we use the method worksheet.rows and to get all the columns of the worksheet we use the method worksheet.columns. Similarly, to iterate only through the values we use the method worksheet.values.


Example:

for row in ws.values:
  for value in row:
  print(value)

 

WRITING DATA TO AN EXCEL FILE

Writing to a workbook can be done in many ways such as adding a formula, adding charts, images, updating cell values, inserting rows and columns, etc… We will discuss each of these with an example.

 

CREATING AND SAVING A NEW WORKBOOK

 

#creates a new workbook
wb = openpyxl.Workbook()

#saving the workbook
wb.save("new.xlsx")

 

ADDING AND REMOVING SHEETS

 

#creating a new sheet
ws1 = wb.create_sheet(title = "sheet 2")

#creating a new sheet at index 0
ws2 = wb.create_sheet(index = 0, title = "sheet 0")

#checking the sheet names
wb.sheetnames['sheet 0', 'Sheet', 'sheet 2']

#deleting a sheet
del wb['sheet 0']

#checking sheetnames
wb.sheetnames['Sheet', 'sheet 2']

 

ADDING CELL VALUES

 

#checking the sheet value
ws['B2'].value
null

#adding value to cell
ws['B2'] = 367

#checking value
ws['B2'].value
367

 

ADDING FORMULAS

 

We often require formulas to be included in our Excel datasheet. We can easily add formulas using the Openpyxl module just like you add values to a cell.
 

For example:

import openpyxl
from openpyxl
import Workbook

wb = openpyxl.load_workbook("new1.xlsx")
ws = wb['Sheet']

ws['A9'] = '=SUM(A2:A8)'

wb.save("new2.xlsx")

The above program will add the formula (=SUM(A2:A8)) in cell A9. The result will be as below.

image

 

MERGE/UNMERGE CELLS

Two or more cells can be merged to a rectangular area using the method merge_cells(), and similarly, they can be unmerged using the method unmerge_cells().

For example:
Merge cells

#merge cells B2 to C9
ws.merge_cells('B2:C9')
ws['B2'] = "Merged cells"

Adding the above code to the previous example will merge cells as below.

image

UNMERGE CELLS

 

#unmerge cells B2 to C9
ws.unmerge_cells('B2:C9')

The above code will unmerge cells from B2 to C9.

INSERTING AN IMAGE

To insert an image we import the image function from the module openpyxl.drawing.image. We then load our image and add it to the cell as shown in the below example.

Example:

import openpyxl
from openpyxl
import Workbook
from openpyxl.drawing.image
import Image

wb = openpyxl.load_workbook("new1.xlsx")
ws = wb['Sheet']
#loading the image(should be in same folder)
img = Image('logo.png')
ws['A1'] = "Adding image"
#adjusting size
img.height = 130
img.width = 200
#adding img to cell A3

ws.add_image(img, 'A3')

wb.save("new2.xlsx")

Result:

image

CREATING CHARTS

Charts are essential to show a visualization of data. We can create charts from Excel data using the Openpyxl module chart. Different forms of charts such as line charts, bar charts, 3D line charts, etc., can be created. We need to create a reference that contains the data to be used for the chart, which is nothing but a selection of cells (rows and columns). I am using sample data to create a 3D bar chart in the below example:

Example

import openpyxl
from openpyxl
import Workbook
from openpyxl.chart
import BarChart3D, Reference, series

wb = openpyxl.load_workbook("example.xlsx")
ws = wb.active

values = Reference(ws, min_col = 3, min_row = 2, max_col = 3, max_row = 40)
chart = BarChart3D()
chart.add_data(values)
ws.add_chart(chart, "E3")
wb.save("MyChart.xlsx")

Result
image


How to Automate Excel with Python with Video Tutorial

Welcome to another video! In this video, We will cover how we can use python to automate Excel. I'll be going over everything from creating workbooks to accessing individual cells and stylizing cells. There is a ton of things that you can do with Excel but I'll just be covering the core/base things in OpenPyXl.

⭐️ Timestamps ⭐️
00:00 | Introduction
02:14 | Installing openpyxl
03:19 | Testing Installation
04:25 | Loading an Existing Workbook
06:46 | Accessing Worksheets
07:37 | Accessing Cell Values
08:58 | Saving Workbooks
09:52 | Creating, Listing and Changing Sheets
11:50 | Creating a New Workbook
12:39 | Adding/Appending Rows
14:26 | Accessing Multiple Cells
20:46 | Merging Cells
22:27 | Inserting and Deleting Rows
23:35 | Inserting and Deleting Columns
24:48 | Copying and Moving Cells
26:06 | Practical Example, Formulas & Cell Styling

📄 Resources 📄
OpenPyXL Docs: https://openpyxl.readthedocs.io/en/stable/ 
Code Written in This Tutorial: https://github.com/techwithtim/ExcelPythonTutorial 
Subscribe: https://www.youtube.com/c/TechWithTim/featured 

#python 

Rupert  Beatty

Rupert Beatty

1667617740

Swift-style-guide: Linkedin's Official Swift Style Guide

Swift Style Guide

Make sure to read Apple's API Design Guidelines.

Specifics from these guidelines + additional remarks are mentioned below.

This guide was last updated for Swift 4.0 on February 14, 2018.

1. Code Formatting

  • 1.1 Use 4 spaces for tabs.
  • 1.2 Avoid uncomfortably long lines with a hard maximum of 160 characters per line (Xcode->Preferences->Text Editing->Page guide at column: 160 is helpful for this)
  • 1.3 Ensure that there is a newline at the end of every file.
  • 1.4 Ensure that there is no trailing whitespace anywhere (Xcode->Preferences->Text Editing->Automatically trim trailing whitespace + Including whitespace-only lines).
  • 1.5 Do not place opening braces on new lines - we use the 1TBS style.
class SomeClass {
    func someMethod() {
        if x == y {
            /* ... */
        } else if x == z {
            /* ... */
        } else {
            /* ... */
        }
    }

    /* ... */
}
  • 1.6 When writing a type for a property, constant, variable, a key for a dictionary, a function argument, a protocol conformance, or a superclass, don't add a space before the colon.
// specifying type
let pirateViewController: PirateViewController

// dictionary syntax (note that we left-align as opposed to aligning colons)
let ninjaDictionary: [String: AnyObject] = [
    "fightLikeDairyFarmer": false,
    "disgusting": true
]

// declaring a function
func myFunction<T, U: SomeProtocol>(firstArgument: U, secondArgument: T) where T.RelatedType == U {
    /* ... */
}

// calling a function
someFunction(someArgument: "Kitten")

// superclasses
class PirateViewController: UIViewController {
    /* ... */
}

// protocols
extension PirateViewController: UITableViewDataSource {
    /* ... */
}
  • 1.7 In general, there should be a space following a comma.
let myArray = [1, 2, 3, 4, 5]
  • 1.8 There should be a space before and after a binary operator such as +, ==, or ->. There should also not be a space after a ( and before a ).
let myValue = 20 + (30 / 2) * 3
if 1 + 1 == 3 {
    fatalError("The universe is broken.")
}
func pancake(with syrup: Syrup) -> Pancake {
    /* ... */
}
  • 1.9 We follow Xcode's recommended indentation style (i.e. your code should not change if CTRL-I is pressed). When declaring a function that spans multiple lines, prefer using that syntax to which Xcode, as of version 7.3, defaults.
// Xcode indentation for a function declaration that spans multiple lines
func myFunctionWithManyParameters(parameterOne: String,
                                  parameterTwo: String,
                                  parameterThree: String) {
    // Xcode indents to here for this kind of statement
    print("\(parameterOne) \(parameterTwo) \(parameterThree)")
}

// Xcode indentation for a multi-line `if` statement
if myFirstValue > (mySecondValue + myThirdValue)
    && myFourthValue == .someEnumValue {

    // Xcode indents to here for this kind of statement
    print("Hello, World!")
}
  • 1.10 When calling a function that has many parameters, put each argument on a separate line with a single extra indentation.
someFunctionWithManyArguments(
    firstArgument: "Hello, I am a string",
    secondArgument: resultFromSomeFunction(),
    thirdArgument: someOtherLocalProperty)
  • 1.11 When dealing with an implicit array or dictionary large enough to warrant splitting it into multiple lines, treat the [ and ] as if they were braces in a method, if statement, etc. Closures in a method should be treated similarly.
someFunctionWithABunchOfArguments(
    someStringArgument: "hello I am a string",
    someArrayArgument: [
        "dadada daaaa daaaa dadada daaaa daaaa dadada daaaa daaaa",
        "string one is crazy - what is it thinking?"
    ],
    someDictionaryArgument: [
        "dictionary key 1": "some value 1, but also some more text here",
        "dictionary key 2": "some value 2"
    ],
    someClosure: { parameter1 in
        print(parameter1)
    })
  • 1.12 Prefer using local constants or other mitigation techniques to avoid multi-line predicates where possible.
// PREFERRED
let firstCondition = x == firstReallyReallyLongPredicateFunction()
let secondCondition = y == secondReallyReallyLongPredicateFunction()
let thirdCondition = z == thirdReallyReallyLongPredicateFunction()
if firstCondition && secondCondition && thirdCondition {
    // do something
}

// NOT PREFERRED
if x == firstReallyReallyLongPredicateFunction()
    && y == secondReallyReallyLongPredicateFunction()
    && z == thirdReallyReallyLongPredicateFunction() {
    // do something
}

2. Naming

2.1 There is no need for Objective-C style prefixing in Swift (e.g. use just GuybrushThreepwood instead of LIGuybrushThreepwood).

2.2 Use PascalCase for type names (e.g. struct, enum, class, typedef, associatedtype, etc.).

2.3 Use camelCase (initial lowercase letter) for function, method, property, constant, variable, argument names, enum cases, etc.

2.4 When dealing with an acronym or other name that is usually written in all caps, actually use all caps in any names that use this in code. The exception is if this word is at the start of a name that needs to start with lowercase - in this case, use all lowercase for the acronym.

// "HTML" is at the start of a constant name, so we use lowercase "html"
let htmlBodyContent: String = "<p>Hello, World!</p>"
// Prefer using ID to Id
let profileID: Int = 1
// Prefer URLFinder to UrlFinder
class URLFinder {
    /* ... */
}
  • 2.5 All constants that are instance-independent should be static. All such static constants should be placed in a marked section of their class, struct, or enum. For classes with many constants, you should group constants that have similar or the same prefixes, suffixes and/or use cases.
// PREFERRED    
class MyClassName {
    // MARK: - Constants
    static let buttonPadding: CGFloat = 20.0
    static let indianaPi = 3
    static let shared = MyClassName()
}

// NOT PREFERRED
class MyClassName {
    // Don't use `k`-prefix
    static let kButtonPadding: CGFloat = 20.0

    // Don't namespace constants
    enum Constant {
        static let indianaPi = 3
    }
}
  • 2.6 For generics and associated types, use a PascalCase word that describes the generic. If this word clashes with a protocol that it conforms to or a superclass that it subclasses, you can append a Type suffix to the associated type or generic name.
class SomeClass<Model> { /* ... */ }
protocol Modelable {
    associatedtype Model
}
protocol Sequence {
    associatedtype IteratorType: Iterator
}
  • 2.7 Names should be descriptive and unambiguous.
// PREFERRED
class RoundAnimatingButton: UIButton { /* ... */ }

// NOT PREFERRED
class CustomButton: UIButton { /* ... */ }
  • 2.8 Do not abbreviate, use shortened names, or single letter names.
// PREFERRED
class RoundAnimatingButton: UIButton {
    let animationDuration: NSTimeInterval

    func startAnimating() {
        let firstSubview = subviews.first
    }

}

// NOT PREFERRED
class RoundAnimating: UIButton {
    let aniDur: NSTimeInterval

    func srtAnmating() {
        let v = subviews.first
    }
}
  • 2.9 Include type information in constant or variable names when it is not obvious otherwise.
// PREFERRED
class ConnectionTableViewCell: UITableViewCell {
    let personImageView: UIImageView

    let animationDuration: TimeInterval

    // it is ok not to include string in the ivar name here because it's obvious
    // that it's a string from the property name
    let firstName: String

    // though not preferred, it is OK to use `Controller` instead of `ViewController`
    let popupController: UIViewController
    let popupViewController: UIViewController

    // when working with a subclass of `UIViewController` such as a table view
    // controller, collection view controller, split view controller, etc.,
    // fully indicate the type in the name.
    let popupTableViewController: UITableViewController

    // when working with outlets, make sure to specify the outlet type in the
    // property name.
    @IBOutlet weak var submitButton: UIButton!
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var nameLabel: UILabel!

}

// NOT PREFERRED
class ConnectionTableViewCell: UITableViewCell {
    // this isn't a `UIImage`, so shouldn't be called image
    // use personImageView instead
    let personImage: UIImageView

    // this isn't a `String`, so it should be `textLabel`
    let text: UILabel

    // `animation` is not clearly a time interval
    // use `animationDuration` or `animationTimeInterval` instead
    let animation: TimeInterval

    // this is not obviously a `String`
    // use `transitionText` or `transitionString` instead
    let transition: String

    // this is a view controller - not a view
    let popupView: UIViewController

    // as mentioned previously, we don't want to use abbreviations, so don't use
    // `VC` instead of `ViewController`
    let popupVC: UIViewController

    // even though this is still technically a `UIViewController`, this property
    // should indicate that we are working with a *Table* View Controller
    let popupViewController: UITableViewController

    // for the sake of consistency, we should put the type name at the end of the
    // property name and not at the start
    @IBOutlet weak var btnSubmit: UIButton!
    @IBOutlet weak var buttonSubmit: UIButton!

    // we should always have a type in the property name when dealing with outlets
    // for example, here, we should have `firstNameLabel` instead
    @IBOutlet weak var firstName: UILabel!
}

2.10 When naming function arguments, make sure that the function can be read easily to understand the purpose of each argument.

2.11 As per Apple's API Design Guidelines, a protocol should be named as nouns if they describe what something is doing (e.g. Collection) and using the suffixes able, ible, or ing if it describes a capability (e.g. Equatable, ProgressReporting). If neither of those options makes sense for your use case, you can add a Protocol suffix to the protocol's name as well. Some example protocols are below.

// here, the name is a noun that describes what the protocol does
protocol TableViewSectionProvider {
    func rowHeight(at row: Int) -> CGFloat
    var numberOfRows: Int { get }
    /* ... */
}

// here, the protocol is a capability, and we name it appropriately
protocol Loggable {
    func logCurrentState()
    /* ... */
}

// suppose we have an `InputTextView` class, but we also want a protocol
// to generalize some of the functionality - it might be appropriate to
// use the `Protocol` suffix here
protocol InputTextViewProtocol {
    func sendTrackingEvent()
    func inputText() -> String
    /* ... */
}

3. Coding Style

3.1 General

3.1.1 Prefer let to var whenever possible.

3.1.2 Prefer the composition of map, filter, reduce, etc. over iterating when transforming from one collection to another. Make sure to avoid using closures that have side effects when using these methods.

// PREFERRED
let stringOfInts = [1, 2, 3].flatMap { String($0) }
// ["1", "2", "3"]

// NOT PREFERRED
var stringOfInts: [String] = []
for integer in [1, 2, 3] {
    stringOfInts.append(String(integer))
}

// PREFERRED
let evenNumbers = [4, 8, 15, 16, 23, 42].filter { $0 % 2 == 0 }
// [4, 8, 16, 42]

// NOT PREFERRED
var evenNumbers: [Int] = []
for integer in [4, 8, 15, 16, 23, 42] {
    if integer % 2 == 0 {
        evenNumbers.append(integer)
    }
}

3.1.3 Prefer not declaring types for constants or variables if they can be inferred anyway.

3.1.4 If a function returns multiple values, prefer returning a tuple to using inout arguments (it’s best to use labeled tuples for clarity on what you’re returning if it is not otherwise obvious). If you use a certain tuple more than once, consider using a typealias. If you’re returning 3 or more items in a tuple, consider using a struct or class instead.

func pirateName() -> (firstName: String, lastName: String) {
    return ("Guybrush", "Threepwood")
}

let name = pirateName()
let firstName = name.firstName
let lastName = name.lastName

3.1.5 Be wary of retain cycles when creating delegates/protocols for your classes; typically, these properties should be declared weak.

3.1.6 Be careful when calling self directly from an escaping closure as this can cause a retain cycle - use a capture list when this might be the case:

myFunctionWithEscapingClosure() { [weak self] (error) -> Void in
    // you can do this

    self?.doSomething()

    // or you can do this

    guard let strongSelf = self else {
        return
    }

    strongSelf.doSomething()
}

3.1.7 Don't use labeled breaks.

3.1.8 Don't place parentheses around control flow predicates.

// PREFERRED
if x == y {
    /* ... */
}

// NOT PREFERRED
if (x == y) {
    /* ... */
}
  • 3.1.9 Avoid writing out an enum type where possible - use shorthand.
// PREFERRED
imageView.setImageWithURL(url, type: .person)

// NOT PREFERRED
imageView.setImageWithURL(url, type: AsyncImageView.Type.person)
  • 3.1.10 Don’t use shorthand for class methods since it is generally more difficult to infer the context from class methods as opposed to enums.
// PREFERRED
imageView.backgroundColor = UIColor.white

// NOT PREFERRED
imageView.backgroundColor = .white

3.1.11 Prefer not writing self. unless it is required.

3.1.12 When writing methods, keep in mind whether the method is intended to be overridden or not. If not, mark it as final, though keep in mind that this will prevent the method from being overwritten for testing purposes. In general, final methods result in improved compilation times, so it is good to use this when applicable. Be particularly careful, however, when applying the final keyword in a library since it is non-trivial to change something to be non-final in a library as opposed to have changing something to be non-final in your local project.

3.1.13 When using a statement such as else, catch, etc. that follows a block, put this keyword on the same line as the block. Again, we are following the 1TBS style here. Example if/else and do/catch code is below.

if someBoolean {
    // do something
} else {
    // do something else
}

do {
    let fileContents = try readFile("filename.txt")
} catch {
    print(error)
}

3.1.14 Prefer static to class when declaring a function or property that is associated with a class as opposed to an instance of that class. Only use class if you specifically need the functionality of overriding that function or property in a subclass, though consider using a protocol to achieve this instead.

3.1.15 If you have a function that takes no arguments, has no side effects, and returns some object or value, prefer using a computed property instead.

3.2 Access Modifiers

  • 3.2.1 Write the access modifier keyword first if it is needed.
// PREFERRED
private static let myPrivateNumber: Int

// NOT PREFERRED
static private let myPrivateNumber: Int
  • 3.2.2 The access modifier keyword should not be on a line by itself - keep it inline with what it is describing.
// PREFERRED
open class Pirate {
    /* ... */
}

// NOT PREFERRED
open
class Pirate {
    /* ... */
}

3.2.3 In general, do not write the internal access modifier keyword since it is the default.

3.2.4 If a property needs to be accessed by unit tests, you will have to make it internal to use @testable import ModuleName. If a property should be private, but you declare it to be internal for the purposes of unit testing, make sure you add an appropriate bit of documentation commenting that explains this. You can make use of the - warning: markup syntax for clarity as shown below.

/**
 This property defines the pirate's name.
 - warning: Not `private` for `@testable`.
 */
let pirateName = "LeChuck"

3.2.5 Prefer private to fileprivate where possible.

3.2.6 When choosing between public and open, prefer open if you intend for something to be subclassable outside of a given module and public otherwise. Note that anything internal and above can be subclassed in tests by using @testable import, so this shouldn't be a reason to use open. In general, lean towards being a bit more liberal with using open when it comes to libraries, but a bit more conservative when it comes to modules in a codebase such as an app where it is easy to change things in multiple modules simultaneously.

3.3 Custom Operators

Prefer creating named functions to custom operators.

If you want to introduce a custom operator, make sure that you have a very good reason why you want to introduce a new operator into global scope as opposed to using some other construct.

You can override existing operators to support new types (especially ==). However, your new definitions must preserve the semantics of the operator. For example, == must always test equality and return a boolean.

3.4 Switch Statements and enums

3.4.1 When using a switch statement that has a finite set of possibilities (enum), do NOT include a default case. Instead, place unused cases at the bottom and use the break keyword to prevent execution.

3.4.2 Since switch cases in Swift break by default, do not include the break keyword if it is not needed.

3.4.3 The case statements should line up with the switch statement itself as per default Swift standards.

3.4.4 When defining a case that has an associated value, make sure that this value is appropriately labeled as opposed to just types (e.g. case hunger(hungerLevel: Int) instead of case hunger(Int)).

enum Problem {
    case attitude
    case hair
    case hunger(hungerLevel: Int)
}

func handleProblem(problem: Problem) {
    switch problem {
    case .attitude:
        print("At least I don't have a hair problem.")
    case .hair:
        print("Your barber didn't know when to stop.")
    case .hunger(let hungerLevel):
        print("The hunger level is \(hungerLevel).")
    }
}

3.4.5 Prefer lists of possibilities (e.g. case 1, 2, 3:) to using the fallthrough keyword where possible).

3.4.6 If you have a default case that shouldn't be reached, preferably throw an error (or handle it some other similar way such as asserting).

func handleDigit(_ digit: Int) throws {
    switch digit {
    case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9:
        print("Yes, \(digit) is a digit!")
    default:
        throw Error(message: "The given number was not a digit.")
    }
}

3.5 Optionals

3.5.1 The only time you should be using implicitly unwrapped optionals is with @IBOutlets. In every other case, it is better to use a non-optional or regular optional property. Yes, there are cases in which you can probably "guarantee" that the property will never be nil when used, but it is better to be safe and consistent. Similarly, don't use force unwraps.

3.5.2 Don't use as! or try!.

3.5.3 If you don't plan on actually using the value stored in an optional, but need to determine whether or not this value is nil, explicitly check this value against nil as opposed to using if let syntax.

// PREFERRED
if someOptional != nil {
    // do something
}

// NOT PREFERRED
if let _ = someOptional {
    // do something
}
  • 3.5.4 Don't use unowned. You can think of unowned as somewhat of an equivalent of a weak property that is implicitly unwrapped (though unowned has slight performance improvements on account of completely ignoring reference counting). Since we don't ever want to have implicit unwraps, we similarly don't want unowned properties.
// PREFERRED
weak var parentViewController: UIViewController?

// NOT PREFERRED
weak var parentViewController: UIViewController!
unowned var parentViewController: UIViewController
  • 3.5.5 When unwrapping optionals, use the same name for the unwrapped constant or variable where appropriate.
guard let myValue = myValue else {
    return
}
  • 3.5.6 Use XCTUnwrap instead of forced unwrapping in tests. ```swift func isEvenNumber(_ number: Int) -> Bool { return number % 2 == 0 }

// PREFERRED func testWithXCTUnwrap() throws { let number: Int? = functionThatReturnsOptionalNumber() XCTAssertTrue(isEvenNumber(try XCTUnwrap(number))) }

// NOT PREFERRED func testWithForcedUnwrap() { let number: Int? = functionThatReturnsOptionalNumber() XCTAssertTrue(isEvenNumber(number!)) // may crash the simulator }


### 3.6 Protocols

When implementing protocols, there are two ways of organizing your code:

1. Using `// MARK:` comments to separate your protocol implementation from the rest of your code
2. Using an extension outside your `class`/`struct` implementation code, but in the same source file

Keep in mind that when using an extension, however, the methods in the extension can't be overridden by a subclass, which can make testing difficult. If this is a common use case, it might be better to stick with method #1 for consistency. Otherwise, method #2 allows for cleaner separation of concerns.

Even when using method #2, add `// MARK:` statements anyway for easier readability in Xcode's method/property/class/etc. list UI.

### 3.7 Properties

* **3.7.1** If making a read-only, computed property, provide the getter without the `get {}` around it.

```swift
var computedProperty: String {
    if someBool {
        return "I'm a mighty pirate!"
    }
    return "I'm selling these fine leather jackets."
}
  • 3.7.2 When using get {}, set {}, willSet, and didSet, indent these blocks.
  • 3.7.3 Though you can create a custom name for the new or old value for willSet/didSet and set, use the standard newValue/oldValue identifiers that are provided by default.
var storedProperty: String = "I'm selling these fine leather jackets." {
    willSet {
        print("will set to \(newValue)")
    }
    didSet {
        print("did set from \(oldValue) to \(storedProperty)")
    }
}

var computedProperty: String  {
    get {
        if someBool {
            return "I'm a mighty pirate!"
        }
        return storedProperty
    }
    set {
        storedProperty = newValue
    }
}
  • 3.7.4 You can declare a singleton property as follows:
class PirateManager {
    static let shared = PirateManager()

    /* ... */
}

3.8 Closures

  • 3.8.1 If the types of the parameters are obvious, it is OK to omit the type name, but being explicit is also OK. Sometimes readability is enhanced by adding clarifying detail and sometimes by taking repetitive parts away - use your best judgment and be consistent.
// omitting the type
doSomethingWithClosure() { response in
    print(response)
}

// explicit type
doSomethingWithClosure() { response: NSURLResponse in
    print(response)
}

// using shorthand in a map statement
[1, 2, 3].flatMap { String($0) }
  • 3.8.2 If specifying a closure as a type, you don’t need to wrap it in parentheses unless it is required (e.g. if the type is optional or the closure is within another closure). Always wrap the arguments in the closure in a set of parentheses - use () to indicate no arguments and use Void to indicate that nothing is returned.
let completionBlock: (Bool) -> Void = { (success) in
    print("Success? \(success)")
}

let completionBlock: () -> Void = {
    print("Completed!")
}

let completionBlock: (() -> Void)? = nil

3.8.3 Keep parameter names on same line as the opening brace for closures when possible without too much horizontal overflow (i.e. ensure lines are less than 160 characters).

3.8.4 Use trailing closure syntax unless the meaning of the closure is not obvious without the parameter name (an example of this could be if a method has parameters for success and failure closures).

// trailing closure
doSomething(1.0) { (parameter1) in
    print("Parameter 1 is \(parameter1)")
}

// no trailing closure
doSomething(1.0, success: { (parameter1) in
    print("Success with \(parameter1)")
}, failure: { (parameter1) in
    print("Failure with \(parameter1)")
})

3.9 Arrays

3.9.1 In general, avoid accessing an array directly with subscripts. When possible, use accessors such as .first or .last, which are optional and won’t crash. Prefer using a for item in items syntax when possible as opposed to something like for i in 0 ..< items.count. If you need to access an array subscript directly, make sure to do proper bounds checking. You can use for (index, value) in items.enumerated() to get both the index and the value.

3.9.2 Never use the += or + operator to append/concatenate to arrays. Instead, use .append() or .append(contentsOf:) as these are far more performant (at least with respect to compilation) in Swift's current state. If you are declaring an array that is based on other arrays and want to keep it immutable, instead of let myNewArray = arr1 + arr2, use let myNewArray = [arr1, arr2].joined().

3.10 Error Handling

Suppose a function myFunction is supposed to return a String, however, at some point it can run into an error. A common approach is to have this function return an optional String? where we return nil if something went wrong.

Example:

func readFile(named filename: String) -> String? {
    guard let file = openFile(named: filename) else {
        return nil
    }

    let fileContents = file.read()
    file.close()
    return fileContents
}

func printSomeFile() {
    let filename = "somefile.txt"
    guard let fileContents = readFile(named: filename) else {
        print("Unable to open file \(filename).")
        return
    }
    print(fileContents)
}

Instead, we should be using Swift's try/catch behavior when it is appropriate to know the reason for the failure.

You can use a struct such as the following:

struct Error: Swift.Error {
    public let file: StaticString
    public let function: StaticString
    public let line: UInt
    public let message: String

    public init(message: String, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) {
        self.file = file
        self.function = function
        self.line = line
        self.message = message
    }
}

Example usage:

func readFile(named filename: String) throws -> String {
    guard let file = openFile(named: filename) else {
        throw Error(message: "Unable to open file named \(filename).")
    }

    let fileContents = file.read()
    file.close()
    return fileContents
}

func printSomeFile() {
    do {
        let fileContents = try readFile(named: filename)
        print(fileContents)
    } catch {
        print(error)
    }
}

There are some exceptions in which it does make sense to use an optional as opposed to error handling. When the result should semantically potentially be nil as opposed to something going wrong while retrieving the result, it makes sense to return an optional instead of using error handling.

In general, if a method can "fail", and the reason for the failure is not immediately obvious if using an optional return type, it probably makes sense for the method to throw an error.

3.11 Using guard Statements

  • 3.11.1 In general, we prefer to use an "early return" strategy where applicable as opposed to nesting code in if statements. Using guard statements for this use-case is often helpful and can improve the readability of the code.
// PREFERRED
func eatDoughnut(at index: Int) {
    guard index >= 0 && index < doughnuts.count else {
        // return early because the index is out of bounds
        return
    }

    let doughnut = doughnuts[index]
    eat(doughnut)
}

// NOT PREFERRED
func eatDoughnut(at index: Int) {
    if index >= 0 && index < doughnuts.count {
        let doughnut = doughnuts[index]
        eat(doughnut)
    }
}
  • 3.11.2 When unwrapping optionals, prefer guard statements as opposed to if statements to decrease the amount of nested indentation in your code.
// PREFERRED
guard let monkeyIsland = monkeyIsland else {
    return
}
bookVacation(on: monkeyIsland)
bragAboutVacation(at: monkeyIsland)

// NOT PREFERRED
if let monkeyIsland = monkeyIsland {
    bookVacation(on: monkeyIsland)
    bragAboutVacation(at: monkeyIsland)
}

// EVEN LESS PREFERRED
if monkeyIsland == nil {
    return
}
bookVacation(on: monkeyIsland!)
bragAboutVacation(at: monkeyIsland!)
  • 3.11.3 When deciding between using an if statement or a guard statement when unwrapping optionals is not involved, the most important thing to keep in mind is the readability of the code. There are many possible cases here, such as depending on two different booleans, a complicated logical statement involving multiple comparisons, etc., so in general, use your best judgement to write code that is readable and consistent. If you are unsure whether guard or if is more readable or they seem equally readable, prefer using guard.
// an `if` statement is readable here
if operationFailed {
    return
}

// a `guard` statement is readable here
guard isSuccessful else {
    return
}

// double negative logic like this can get hard to read - i.e. don't do this
guard !operationFailed else {
    return
}
  • 3.11.4 If choosing between two different states, it makes more sense to use an if statement as opposed to a guard statement.
// PREFERRED
if isFriendly {
    print("Hello, nice to meet you!")
} else {
    print("You have the manners of a beggar.")
}

// NOT PREFERRED
guard isFriendly else {
    print("You have the manners of a beggar.")
    return
}

print("Hello, nice to meet you!")
  • 3.11.5 You should also use guard only if a failure should result in exiting the current context. Below is an example in which it makes more sense to use two if statements instead of using two guards - we have two unrelated conditions that should not block one another.
if let monkeyIsland = monkeyIsland {
    bookVacation(onIsland: monkeyIsland)
}

if let woodchuck = woodchuck, canChuckWood(woodchuck) {
    woodchuck.chuckWood()
}
  • 3.11.6 Often, we can run into a situation in which we need to unwrap multiple optionals using guard statements. In general, combine unwraps into a single guard statement if handling the failure of each unwrap is identical (e.g. just a return, break, continue, throw, or some other @noescape).
// combined because we just return
guard let thingOne = thingOne,
    let thingTwo = thingTwo,
    let thingThree = thingThree else {
    return
}

// separate statements because we handle a specific error in each case
guard let thingOne = thingOne else {
    throw Error(message: "Unwrapping thingOne failed.")
}

guard let thingTwo = thingTwo else {
    throw Error(message: "Unwrapping thingTwo failed.")
}

guard let thingThree = thingThree else {
    throw Error(message: "Unwrapping thingThree failed.")
}
  • 3.11.7 Don’t use one-liners for guard statements.
// PREFERRED
guard let thingOne = thingOne else {
    return
}

// NOT PREFERRED
guard let thingOne = thingOne else { return }

4. Documentation/Comments

4.1 Documentation

If a function is more complicated than a simple O(1) operation, you should generally consider adding a doc comment for the function since there could be some information that the method signature does not make immediately obvious. If there are any quirks to the way that something was implemented, whether technically interesting, tricky, not obvious, etc., this should be documented. Documentation should be added for complex classes/structs/enums/protocols and properties. All public functions/classes/properties/constants/structs/enums/protocols/etc. should be documented as well (provided, again, that their signature/name does not make their meaning/functionality immediately obvious).

After writing a doc comment, you should option click the function/property/class/etc. to make sure that everything is formatted correctly.

Be sure to check out the full set of features available in Swift's comment markup described in Apple's Documentation.

Guidelines:

4.1.1 160 character column limit (like the rest of the code).

4.1.2 Even if the doc comment takes up one line, use block (/** */).

4.1.3 Do not prefix each additional line with a *.

4.1.4 Use the new - parameter syntax as opposed to the old :param: syntax (make sure to use lower case parameter and not Parameter). Option-click on a method you wrote to make sure the quick help looks correct.

class Human {
    /**
     This method feeds a certain food to a person.

     - parameter food: The food you want to be eaten.
     - parameter person: The person who should eat the food.
     - returns: True if the food was eaten by the person; false otherwise.
    */
    func feed(_ food: Food, to person: Human) -> Bool {
        // ...
    }
}

4.1.5 If you’re going to be documenting the parameters/returns/throws of a method, document all of them, even if some of the documentation ends up being somewhat repetitive (this is preferable to having the documentation look incomplete). Sometimes, if only a single parameter warrants documentation, it might be better to just mention it in the description instead.

4.1.6 For complicated classes, describe the usage of the class with some potential examples as seems appropriate. Remember that markdown syntax is valid in Swift's comment docs. Newlines, lists, etc. are therefore appropriate.

/**
 ## Feature Support

 This class does some awesome things. It supports:

 - Feature 1
 - Feature 2
 - Feature 3

 ## Examples

 Here is an example use case indented by four spaces because that indicates a
 code block:

     let myAwesomeThing = MyAwesomeClass()
     myAwesomeThing.makeMoney()

 ## Warnings

 There are some things you should be careful of:

 1. Thing one
 2. Thing two
 3. Thing three
 */
class MyAwesomeClass {
    /* ... */
}
  • 4.1.7 When mentioning code, use code ticks - `
/**
 This does something with a `UIViewController`, perchance.
 - warning: Make sure that `someValue` is `true` before running this function.
 */
func myFunction() {
    /* ... */
}
  • 4.1.8 When writing doc comments, prefer brevity where possible.

4.2 Other Commenting Guidelines

  • 4.2.1 Always leave a space after //.
  • 4.2.2 Always leave comments on their own line.
  • 4.2.3 When using // MARK: - whatever, leave a newline after the comment.
class Pirate {

    // MARK: - instance properties

    private let pirateName: String

    // MARK: - initialization

    init() {
        /* ... */
    }

}

Download Details:

Author: linkedin
Source Code: https://github.com/linkedin/swift-style-guide 
License: View license

#swift #style #guide #ios 

Billy Chandler

Billy Chandler

1675498447

Convert a String to a Datetime Object in Python

Convert a string to a datetime object in Python using the strptime() method. Using the datetime.strptime() method to convert strings to datetime objects. 

Python offers a variety of built-in modules that you can include in your program.

A module is a Python file containing the necessary code to execute an individual functionality. This file is imported into your application to help you perform a specific task.

One of those modules is the datetime module for working with and manipulating times and dates.

The datetime module includes the datetime class, which in turn provides the strptime() class method. The strptime() method creates a datetime object from a string representation of a corresponding date and time.

In this article, you will learn how to use the datetime.strptime() method to convert strings to datetime objects.

Let's get into it!

What Is the datetime.strptime() Method in Python? A datetime.strptime() Syntax Breakdown

The general syntax for the datetime.strptime() method looks something similar to the following:

datetime.strptime(date_string, format_code)

Let's break it down.

Firstly, datetime is the class name.

Then, strptime() is the method name. The method accepts two required string arguments.

  • The first required argument is date_string – the string representation of the date you want to convert to a datetime object.
  • The second required argument is format_code – a specific format to help you convert the string to a datetime object.

Here is a brief list of some of the most commonly used code formats you may come across:

  • %d - the day of the month as a zero-padded decimal number such as 28.
  • %a - a day's abbreviated name, such as Sun.
  • %A - a day's full name, such as Sunday.
  • %m - the month as a zero-padded decimal number, such as 01.
  • %b - month's abbreviated name, such as Jan.
  • %B - the month's full name, such as January.
  • %y - the year without century, such as 23.
  • %Y- the year with century, such as 2023.
  • %H - the hours of the day in a 24-hour format, such as 08.
  • %I - the hours of the day in a 12-hour format.
  • %M - the minutes in an hour, such as 20.
  • %S - the seconds in a minute, such as 00.

To view a table that shows all of the format codes for datetime.strptime(), refer to the Python documentation.

How to Use the datetime.strptime() Method in Python? How to Convert a String to a Datetime Object in Python

Let's say I have the following string that represents a date and time:

28/01/23  08:20:00

And I want to get the following output:

2023-01-28 08:20:00

How would I achieve that?

Let's take a look at the code below:

# import the datetime class from the datetime module
from datetime import datetime

date_time_str = "28/01/23  08:20:00"

# check data type of date_time_str
print(type(date_time_str))

# output

# <class 'str'>

First, I import the datetime module with the from datetime import datetime statement.

Then, I store the string I want to convert to a datetime object in a variable named date_time_str and check its type using the type() function. The output indicates that it is a string.

Now, let's convert the string to a datetime object using the strptime() method of the datetime class and check the data type:

from datetime import datetime

date_time_str = "28/01/23  08:20:00"

date_time_object = datetime.strptime(date_time_str, "%d/%m/%y %H:%M:%S")

print(date_time_object)

# check date_time_object_type
print(type(date_time_object))

# output

# 2023-01-28 08:20:00
# <class 'datetime.datetime'>

The format codes for the string 28/01/23 08:20:00 are %d/%m/%y %H:%M:%S.

The format codes %d,%m,%y,%H,%M,%S represent the day of the month, the month as a zero-padded decimal number, the year without century, the hour of the day, the minutes of the day and the seconds of the day, respectively.

Now, let's change the initial string a bit.

Let's change it from 28/01/23 to 28 January 2023 and check the data type of date_time_str:

from datetime import datetime

date_time_str = "28 January 2023 08:20:00"

#check data type
print(type(date_time_str))

# output

# <class 'str'>

Now, let's convert date_time_str to a datetime object – keep in mind that because the string is different, you must also change the format codes:

from datetime import datetime

date_time_str = "28 January 2023 08:20:00"

date_object = datetime.strptime(date_time_str, "%d %B %Y %H:%M:%S")

print(date_object)

#check data type
print(type(date_object))

# output

# 2023-01-28 08:20:00
# <class 'datetime.datetime'>

The format codes for the string 28 January 2023 08:20:00 are %d %B %Y %H:%M:%S.

Because I changed the month of January from its zero-padded decimal number representation, 01, to its full name, January, I also needed to change its format code – from %m to %B.

How to Convert a String to a datetime.date() Object in Python

What if you only want to convert the date but not the time from a string?

You may only want to convert only the 28/01/23 part of the 28/01/23 08:20:00 string to an object.

To convert a string to a date object, you will use the strptime() method like you saw in the previous section, but you will also use the datetime.date() method to extract only the date.

from datetime import datetime

date_time_str = "28 January 2023 08:20:00"

date_object = datetime.strptime(date_time_str, "%d %B %Y %H:%M:%S").date()

print(date_object)

#check data type
print(type(date_object))

# output

# 2023-01-28
# <class 'datetime.date'>

How to Convert a String to a datetime.time() Object in Python

And to convert only the time part,08:20:00 from the 28/01/23 08:20:00 string, you would use the datetime.time() method to extract only the time:

from datetime import datetime

date_time_str = "28 January 2023 08:20:00"

date_object = datetime.strptime(date_time_str, "%d %B %Y %H:%M:%S").time()

print(date_object)
print(type(date_object))

# output

# 08:20:00
# <class 'datetime.time'>

Why Does a ValueError Get Raised When Using datetime.strptime() in Python?

Something to keep in mind is that the string you pass as an argument to the strptime() method needs to have a specific format – not any string gets converted into a datetime object.

Specifically, the year, month, and day in the string must match the format code.

For example, the format code for the month in the string 28/01/23 must be %m, which represents the month as a zero-padded decimal number.

What happens when I use the format code %B instead?

from datetime import datetime

date_time_str = "28/01/23  08:20:00"

date_time_object = datetime.strptime(date_time_str, "%d/%B/%y %H:%M:%S")

print(date_time_object)

# output

# raise ValueError("time data %r does not match format %r" %
# ValueError: time data '28/01/23  08:20:00' does not match format '%d/%B/%y # %H:%M:%S'

I get a ValueError!

The %B format code represents the month's full name, such as January, and not 01.

So, if the string passed to strptime() does not match the format specified, a ValueError gets raised.

To help with this, you can test and handle the error by using a try-except block, like so:

from datetime import datetime

date_time_str = "28/01/23  08:20:00"

try:
  date_time_object = datetime.strptime(date_time_str, "%d/%B/%y %H:%M:%S")
except ValueError as error:
  print('A ValueError is raised because :', error)
  
# output

# A ValueError is raised because : time data '28/01/23  08:20:00' does not # match format '%d/%B/%y %H:%M:%S'

Conclusion

Hopefully, this article helped you understand how to convert a string to a datetime object in Python using the strptime() method.

Thank you for reading, and happy coding!

Original article source at https://www.freecodecamp.org

#python 

5 Favorite PHP Libraries for File Manipulation and MIME Type Detection

In today's post we will learn about 5 Favorite PHP Libraries for File Manipulation and MIME Type Detection.

What is MIME type detection?

The most simple way to detect the MIME type of any file is to use MIME_Type's static autoDetect() method. It will try to determine the file's type and return it as a string. If an error occurs, a PEAR_Error object is returned. By default, only the plain MIME type will be returned, without any comments or parameters.

Table of contents:

  • CSV - A CSV data manipulation library.
  • Flysystem - Abstraction for local and remote filesystems.
  • Gaufrette - A filesystem abstraction layer.
  • PHP FFmpeg - A wrapper for the FFmpeg video library.
  • UnifiedArchive - A unified reader and writer of compressed archives.

1 - CSV:

A CSV data manipulation library.

Csv is a library to ease parsing, writing and filtering CSV in PHP. The library goal is to be powerful while remaining lightweight, by utilizing PHP native classes whenever possible.

Highlights

  • Easy to use API
  • Read and Write to CSV documents in a memory efficient and scalable way
  • Support PHP stream filtering capabilities
  • Transform CSV documents into popular format (JSON, XML or HTML)
  • Fully documented
  • Fully unit tested
  • Framework-agnostic

System Requirements

You need the mbstring extension to use Csv and the latest stable version of PHP is recommended.

Please find below the PHP support for Csv version 9.

Min. Library VersionMin. PHP VersionMax. Supported PHP Version
9.0.0PHP 7.0.10PHP 7.1.x
9.1.2PHP 7.0.10PHP 7.2.x
9.2.0PHP 7.0.10PHP 7.4.x
9.6.0PHP 7.2.5PHP 7.4.x
9.6.2PHP 7.2.5PHP 8.0.x
9.7.0PHP 7.3.0PHP 8.0.x
9.7.3PHP 7.3.0PHP 8.1.x
9.8.0PHP 7.4.0PHP 8.1.x

Install

Install Csv using Composer.

composer require league/csv

Configuration

Warning: If your CSV document was created or is read on a Macintosh computer, add the following lines before using the library to help PHP detect line ending.

if (!ini_get("auto_detect_line_endings")) {
    ini_set("auto_detect_line_endings", '1');
}

Testing

The library has a :

To run the tests, run the following command from the project folder.

composer test

View on Github

2 - Flysystem:

Abstraction for local and remote filesystems.

Flysystem is a file storage library for PHP. It provides one interface to interact with many types of filesystems. When you use Flysystem, you're not only protected from vendor lock-in, you'll also have a consistent experience for which ever storage is right for you.

Getting Started

Officially supported adapters

Third party Adapters

You can always create an adapter yourself.

Security

If you discover any security related issues, please email info@frankdejonge.nl instead of using the issue tracker.

View on Github

3 - Gaufrette:

A filesystem abstraction layer.

Gaufrette provides a filesystem abstraction layer.

Why use Gaufrette?

Imagine you have to manage a lot of medias in a PHP project. Lets see how to take this situation in your advantage using Gaufrette.

The filesystem abstraction layer permits you to develop your application without the need to know where all those medias will be stored and how.

Another advantage of this is the possibility to update the files location without any impact on the code apart from the definition of your filesystem. In example, if your project grows up very fast and if your server reaches its limits, you can easily move your medias in an Amazon S3 server or any other solution.

Development

Requires :

  • docker-ce
  • docker-compose

Create .env file :

$ make docker.dev

and configure it as you want.

Build the php docker image :

$ make docker.build

Install dependencies :

$ make docker.all-deps

Run tests :

$ make docker.tests

You can also use a different php version, simply set the PHP_VERSION env var to any of these values when calling a make target :

See the docker-compose.yml file for more details.

You'll need to clear the previously installed dependencies when switching from a version to an other, to do so, run :

$ make clear-deps
$ PHP_VERSION=<the_version_you_want_to_use> make build install-deps

Apply Coding Standards

You should check for CS violations by using

$ make php-cs-compare

and fix them with

$ make php-cs-fix

Note

This project does not have any stable release yet but we do not want to break BC now.

View on Github

4 - PHP FFmpeg:

A wrapper for the FFmpeg video library.

An Object-Oriented library to convert video/audio files with FFmpeg / AVConv.

Installation

This library requires PHP 8.0 or higher. For older versions of PHP, check out the 0.x-branch.

The recommended way to install PHP-FFMpeg is through Composer.

$ composer require php-ffmpeg/php-ffmpeg

Basic Usage

require 'vendor/autoload.php';

$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
$video
    ->filters()
    ->resize(new FFMpeg\Coordinate\Dimension(320, 240))
    ->synchronize();
$video
    ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10))
    ->save('frame.jpg');
$video
    ->save(new FFMpeg\Format\Video\X264(), 'export-x264.mp4')
    ->save(new FFMpeg\Format\Video\WMV(), 'export-wmv.wmv')
    ->save(new FFMpeg\Format\Video\WebM(), 'export-webm.webm');

Documentation

This documentation is an introduction to discover the API. It's recommended to browse the source code as it is self-documented.

FFMpeg

FFMpeg\FFMpeg is the main object to use to manipulate medias. To build it, use the static FFMpeg\FFMpeg::create:

$ffmpeg = FFMpeg\FFMpeg::create();

FFMpeg will autodetect ffmpeg and ffprobe binaries. If you want to give binary paths explicitly, you can pass an array as configuration. A Psr\Logger\LoggerInterface can also be passed to log binary executions.

$ffmpeg = FFMpeg\FFMpeg::create(array(
    'ffmpeg.binaries'  => '/opt/local/ffmpeg/bin/ffmpeg',
    'ffprobe.binaries' => '/opt/local/ffmpeg/bin/ffprobe',
    'timeout'          => 3600, // The timeout for the underlying process
    'ffmpeg.threads'   => 12,   // The number of threads that FFMpeg should use
), $logger);

You may pass a temporary_directory key to specify a path for temporary files.

$ffmpeg = FFMpeg\FFMpeg::create(array(
    'temporary_directory' => '/var/ffmpeg-tmp'
), $logger);

Manipulate media

FFMpeg\FFMpeg creates media based on URIs. URIs could be either a pointer to a local filesystem resource, an HTTP resource or any resource supported by FFmpeg.

Note: To list all supported resource type of your FFmpeg build, use the -protocols command:

ffmpeg -protocols

To open a resource, use the FFMpeg\FFMpeg::open method.

$ffmpeg->open('video.mpeg');

Two types of media can be resolved: FFMpeg\Media\Audio and FFMpeg\Media\Video. A third type, FFMpeg\Media\Frame, is available through videos.

View on Github

5 - UnifiedArchive:

A unified reader and writer of compressed archives.

How it works

UnifiedArchive uses "drivers", which can be one of types:

  1. PHP Extensions
  2. Utilities + bridge
  3. Pure PHP

By default, UA goes top-down to select first available driver for passed archive. So, PHP Extension driver will be used (if available), then Utilities + bridge driver (if available), and then Pure PHP driver.

There is at least one driver in all three types, which handles zip format, so this format can be fully supported in any OS/PHP configuration:

  1. zip / phar PHP extensions
  2. Utility + bridge SevenZip / AlchemyZippy
  3. Pure NelexaZip

tar format (with compressed variants) supported by:

  1. phar PHP extension
  2. Utility + bridge SevenZip / AlchemyZippy
  3. Pure TarByPear

So, there is always one driver that supports popular formats, and you should not remember how to work with this concrete driver (zip/phar/SevenZip/AlchemyZippy/NelexaZip), interface for them is uniform.

Quick start

Installation and configuration

Install library

composer require wapmorgan/unified-archive
#Check supported formats with installed drivers
./vendor/bin/cam system:formats
#Check supported functions for zip format
./vendor/bin/cam system:format zip

Install new driver

#Read installation instructions from
./vendor/bin/cam system:drivers
#install missing drivers, for example pear/archive_tar
composer require pear/archive_tar
#check out driver functions
./vendor/bin/cam system:formats TarByPear

#if needed, install extensions, cli tools and php libraries
#to enable support of other formats

Usage

use \wapmorgan\UnifiedArchive\UnifiedArchive;

$output_dir = '/var/www/extracted';

# Extraction
$archive = UnifiedArchive::open('archive.zip'); // archive.rar, archive.tar.bz2

if (disk_free_space($output_dir) < $archive->getOriginalSize()) {
    throw new \RuntimeException('No needed space available. Need ' . ($archive->getOriginalSize() - disk_free_space($output_dir)) . ' byte(s) more');
}

$extracted = $archive->extract($output_dir);
echo 'Number of extracted files' . $extracted.PHP_EOL;

# Archiving
UnifiedArchive::archive([
    'README.md' => '/default/path/to/README.md',
    '' => '/folder/with/content/',
], 'archive.zip');

View on Github

Thank you for following this article.

Related videos:

How to Open ZIP Files With PHP

#php #file #type #detection