Tuesday, March 31, 2020

PSF's Projected 2020 Financial Outcome

The Python Software Foundation (PSF) is a 501(c)(3) non-profit organization dedicated to the Python community and programming language, as well as running PyCon US. Since PyCon US 2020 was cancelled, the community has asked how the PSF’s finances will be affected. Let us take a look at the projected 2020 financial outcome.

Bottom Line

As of today, the PSF will use approximately $627,000 from our financial reserve:
Expenses Revenue
PSF $1,300,000 $550,000 -$750,000
PyCon $280,000 $403,000 $123,000
Total -$627,000
If you are interested in how we arrived at these estimates, continue reading to learn about our projected expenses and revenue for this year. 

Expenses

PyCon US 2020

Pittsburgh and its vendors have been incredibly helpful in reducing or eliminating most of the 2020 conference minimums and cancellation fees. We estimate $280,000 in expenses for pre-conference work related to website/logo design and nonrefundable deposits. In addition, we budgeted significant funds to support travel grantees with non-reimbursable costs, as well as executing PyCon 2020 remote content. Once travel grants and instructor fees are complete, we will revise the expense total. 

PSF

Through March 2020, the PSF awarded several grants*, expended legal fees to protect PyLadies trademarks in dozens of countries, and employed staff. The PSF is projected to spend $1,300,000 in 2020.

Revenue

PyCon US 2020

PyCon US registration and sponsorship revenue is used to produce PyCon, with the largest costs going to food, audio-visual services, and travel grants. 
Our staff works to create the best and most affordable attendee experience possible with the added benefit that 100% of net proceeds fund the PSF. For 2020, we estimated PyCon’s net income at $720,000. As of today, we are estimating PyCon's net income to be $123,000, thanks to individual donations and sponsorship fees. 

PSF

PSF 2020 sponsorships are estimated at $350,000. COVID-19 is impacting financial markets and job security, so we expect individual donations and memberships to decrease in 2020 by 55% from 2019 to around $200,000. 

How can you help?

The PSF’s financial reserve is crucial, as we experienced during the economic downturn of 2008 and again in 2020. The cash reserve prepares us for economic impacts, events out of our control, and provides a stable environment with health benefits for our employees, even during this difficult time. 
Here are ways community members can help and get involved:
  • Become a free or supporting member of the PSF to get involved in our future
  • Donate some or all of your PyCon registration (thank you to those that already have)
  • Donate directly to the PSF
  • Donate some or all of your company's PyCon's sponsorship (thank you to those that already have)
  • Ask your employer to sponsor the PSF
  • Ask your employer if they match donations to 501(c)(3) non-profits, and ask for your donations to the PSF to be matched
  • Sign up for the PSF’s free newsletter to stay up to date

We wish our entire community good health.
* PSF Grants: When PyCon 2020 was cancelled, the PSF paused its Grants Program until we can find virtual options and other ways to support events, as well as fully understand the PSF’s financial situation.


from Python Software Foundation News
via read more

Comparing Python Objects the Right Way: "is" vs "=="

There’s a subtle difference between the Python identity operator (is) and the equality operator (==). Your code can run fine when you use the Python is operator to compare numbers, until it suddenly doesn’t. You might have heard somewhere that the Python is operator is faster than the == operator, or you may feel that it looks more Pythonic. However, it’s crucial to keep in mind that these operators don’t behave quite the same.

The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory. In the vast majority of cases, this means you should use the equality operators == and !=, except when you’re comparing to None.

In this course, you’ll learn:

  • What the difference is between object equality and identity
  • When to use equality and identity operators to compare objects
  • What these Python operators do under the hood
  • Why using is and is not to compare values leads to unexpected behavior
  • How to write a custom __eq__() class method to define equality operator behavior

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]



from Real Python
read more

Codementor: Michael Kennedy almost learned Python in the 90s... and other things I learned recording his DevJourney

Michael Kennedy is a podcaster and a trainer. After interviewing him for the DevJourney podcast, here are the key takeways I personally took out of the discussion.

from Planet Python
via read more

Kushal Das: Introducing ManualBox project

One of the major security features of the QubesOS is the file vaults, where access to specific files can only happen via user input in the GUI applet. Same goes to the split-ssh, where the user has to allow access to the ssh key (actually on a different VM).

I was hoping to have similar access control to important dotfiles with passwords, ssh private keys, and other similar files on my regular desktop system. I am introducing ManualBox which can provide similarly access control on normal Linux Desktops or even on Mac.

GIF of usage

How to install?

Follow the installation guide on the Mac in the wiki. For Linux, we are yet to package the application, and you can directly run from the source (without installing).

git clone https://github.com/kushaldas/manualbox.git
cd manualbox

On Fedora

sudo dnf install python3-cryptography python3-qt5 python3-fusepy python3-psutil fuse -y

On Debian

sudo apt install python3-cryptography python3-pyqt5 python3-fusepy python3-psutil fuse

Usage guide

To start the application from source:

On Linux:

./devscripts/manualbox

On Mac:

Click on the App icon like any other application.

If you are running the tool for the first time, it will create a new manualbox and mount it in ~/secured directory, it will also give you the password, please store it somewhere securely, as you will need it to mount the filesystem from the next time.

initial screen

After selecting (or you can directly type) the mount path (must be an empty directory), you should type in the password, and then click on the Mount button.

File system mounted

Now, if you try to access any file, the tool will show a system notification, and you can either Allow or Deny via the following dialog.

Allow or deny access

Every time you allow file access, it shows the notification message via the system tray icon.

Accessing file msg

To exit the application, first click on the Unmount, and right-click on the systray icon, and click on the Exit or close via window close button.

How to exit from the application

Usage examples (think about your important dotfiles with passwords/tokens)

Note: If you open the mounted directory path from a GUI file browser, you will get too many notifications, as these browsers will open the file many times separately. Better to have you GUI application/command line tool to use those files as required.

Thunderbird

You can store your thuderbird profile into this tool. That way, thunderbird needs your permission for access when you start the application.

ls -l ~/.thunderbird/
# now find your right profile (most people have only one)
mv ~/.thunderbird/xxxxxx.default/logins.json ~/secured/
ln -s ~/secured/logins.json ~/.thunderbird/xxxxxx.default/logins.json

SSH private key

mv ~/.ssh/id_rsa ~/secured/
ln -s ~/secured/id_rsa ~/.ssh/id_rsa

If you have any issues, please file issues or even better a PR along with the issue :)



from Planet Python
via read more

Programiz: Python main function

In this tutorial, we will learn how to use a Python program's __name__ attribute to run it dynamically in different contexts.

from Planet Python
via read more

Mike Driscoll: Python 101 – Learning About Dictionaries

Dictionaries are another fundamental data type in Python. A dictionary is a key, value pair. Some programming languages refer to them as hash tables. They are described as a mapping object that maps hashable values to arbitrary objects.

A dictionary’s keys must be immutable, that is, unable to change. Starting in Python 3.7, dictionaries are ordered. What that means is that when you add a new key, value pair to a dictionary, it remembers what order they were added. Prior to Python 3.7, this was not the case and you could not rely on insertion order.

You will learn how to do the following in this chapter:

  • Create dictionaries
  • Access dictionaries
  • Dictionary methods
  • Modifying dictionaries
  • Deleting from your dictionary

Let’s start off by learning about creating dictionaries!

You can create a dictionary in a couple of different ways. The most common method is by placing a comma-separated list key: value pairs within curly braces.

Let’s look at an example:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict
{'email': 'jdoe@gmail.com', 'first_name': 'James', 'last_name': 'Doe'}

You can also use Python’s built-in dict() function to create a dictionary. dict() will accept a series of keyword arguments (i.e. 1=’one’, 2=’two’, etc), a list of tuples or another dictionary.

Here are a couple of examples:

>>> numbers = dict(one=1, two=2, three=3)
>>> numbers
{'one': 1, 'three': 3, 'two': 2}
>>> info_list = [('first_name', 'James'), ('last_name', 'Doe'), ('email', 'jdoes@gmail.com')]
>>> info_dict = dict(info_list)
>>> info_dict
{'email': 'jdoes@gmail.com', 'first_name': 'James', 'last_name': 'Doe'}

The first example uses dict() on a series of keyword arguments. You will learn more about these when you learn about functions. You can think of keyword arguments as a series of keywords with the equals sign between them and their value.

The second example shows you how to create a list that has 3 tuples inside of it. Then you pass that list to dict() to convert it to a dictionary.

Accessing Dictionaries

Dictionaries claim to fame is that they are very fast. You can access any value in a dictionary via the key. If the key is not found, you will receive a KeyError.

Let’s take a look at how to use a dictionary:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict['first_name']
'James'

To get the value of first_name, you must use the following syntax: dictionary_name[key]

Now let’s try to get a key that doesn’t exist:

>>> sample_dict['address']
Traceback (most recent call last):
   Python Shell, prompt 118, line 1
builtins.KeyError: 'address'

Well that didn’t work! You asked the dictionary to give you a value that wasn’t in the dictionary!

You can use Python’s in keyword to ask if a key is in the dictionary:

>>> 'address' in sample_dict
False
>>> 'first_name' in sample_dict
True

You can also check to see if a key is not in a dictionary by using Python’s not keyword:

>>> 'first_name' not in sample_dict
False
>>> 'address' not in sample_dict
True

Another way to access keys in dictionaries is by using one of the dictionary methods. Let’s find out more about dictionary methods now!

Dictionary Methods

As with most Python data types, dictionaries have special methods you can use. Let’s check out some of the dictionary’s methods!

d.get(key[, default])

You can use the get() method to get a value. get() requires you to specify a key to look for. It optionally allows you to return a default if the key is not found. The default is None. Let’s take a look:

>>> print(sample_dict.get('address'))
None
>>> print(sample_dict.get('address', 'Not Found'))
Not Found

The first example shows you what happens when you try to get() a key that doesn’t exist without setting get‘s default. In that case, it returns None. Then the second example shows you how to set the default to the string “Not Found”.

d.clear()

The clear() method can be used to remove all the items from the dictionary.

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict
{'email': 'jdoe@gmail.com', 'first_name': 'James', 'last_name': 'Doe'}
>>> sample_dict.clear()
>>> sample_dict
{}

d.copy()

If you need to create a shallow copy of the dictionary, then the copy() method is for you:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> copied_dict = sample_dict.copy()
>>> copied_dict
{'email': 'jdoe@gmail.com', 'first_name': 'James', 'last_name': 'Doe'}

If your dictionary has objects or dictionaries inside of it, then you may end up running into logic errors due to this method as changing one dictionary can affect the copy. In those case, you should use Python’s copy module, which has a deepcopy function that will create a completely separate copy for you.

d.items()

The items() method will return a new view of the dictionary’s items:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict.items()
dict_items([('first_name', 'James'), ('last_name', 'Doe'), ('email', 'jdoe@gmail.com')])

This view object will change as the dictionary object itself changes.

d.keys()

If you need to get a view of the keys that are in a dictionary, then keys() is the method for you. As a view object, it will provide you with a dynamic view of the dictionary’s keys. You can iterate over a view and also check membership view the in keyword:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> keys = sample_dict.keys()
>>> keys
dict_keys(['first_name', 'last_name', 'email'])
>>> 'email' in keys
True
>>> len(keys)
3

d.values()

The values() method also returns a view object, but in this case it is a dynamic view of the dictionary’s values:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> values = sample_dict.values()
>>> values
dict_values(['James', 'Doe', 'jdoe@gmail.com'])
>>> 'Doe' in values
True
>>> len(values)
3

d.pop(key[, default])

Do you need to remove a key from a dictionary? Then pop() is the method for you. The pop() method takes a key and an option default string. If you don’t set the default and the key is not found, a KeyError will be raised.

Here are some examples:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict.pop('something')
Traceback (most recent call last):
   Python Shell, prompt 146, line 1
builtins.KeyError: 'something'
>>> sample_dict.pop('something', 'Not found!')
'Not found!'
>>> sample_dict.pop('first_name')
'James'
>>> sample_dict
{'email': 'jdoe@gmail.com', 'last_name': 'Doe'}

d.popitem()

The popitem() method is used to remove and return a (key, value) pair from the dictionary. The pairs are returned in last-in first-out (LIFO) order. If called on an empty dictionary, you will receive a KeyError

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict.popitem()
('email', 'jdoe@gmail.com')
>>> sample_dict
{'first_name': 'James', 'last_name': 'Doe'}

d.update([other])

Update a dictionary with the (key, value) pairs from other, overwriting existing keys. Returns None.

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict.update([('something', 'else')])
>>> sample_dict
{'email': 'jdoe@gmail.com',
'first_name': 'James',
'last_name': 'Doe',
'something': 'else'}

Modifying Your Dictionary

You will need to modify your dictionary from time to time. Let’s assume that you need to add a new key, value pair:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict['address'] = '123 Dunn St'
>>> sample_dict
{'address': '123 Dunn St',
'email': 'jdoe@gmail.com',
'first_name': 'James',
'last_name': 'Doe'}

To add a new item to a dictionary, you can use the square braces to enter a new key and set it to a value.

If you need to update a pre-existing key, you can do the following:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict['email'] = 'jame@doe.com'
>>> sample_dict
{'email': 'jame@doe.com', 'first_name': 'James', 'last_name': 'Doe'}

In this example, you set sample_dict['email'] to jame@doe.com. Whenever you set a pre-existing key to a new value, you will overwrite the previous value.

Deleting Items From Your Dictionary

Sometimes you will need to remove a key from a dictionary. You can use Python’s del keyword for that:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> del sample_dict['email']
>>> sample_dict
{'first_name': 'James', 'last_name': 'Doe'}

In this case, you tell Python to delete the key “email” from sample_dict.

The other method for removing a key is to use the dictionary’s pop() method, which was mentioned in the previous section:

>>> sample_dict = {'first_name': 'James', 'last_name': 'Doe', 'email': 'jdoe@gmail.com'}
>>> sample_dict.pop('email')
'jdoe@gmail.com'
>>> sample_dict
{'first_name': 'James', 'last_name': 'Doe'}

When you use pop(), it will return the value that is being removed.

Wrapping Up

The dictionary data type is extremely useful. You will find it handy to use for quick lookups of all kinds of data. You can set the value of the key: value pair to any object in Python. So you could store lists, tuples, or objects as values in a dictionary.

If you need a dictionary that can create a default when you go to get a key that does not exist, you should take a look at Python’s collections module. It has a defaultdict class that is made for exactly that use case.

Related Reading

 

The post Python 101 – Learning About Dictionaries appeared first on The Mouse Vs. The Python.



from Planet Python
via read more

Why Understanding CVEs Is Critical for Data Scientists

CVEs are Common Vulnerabilities and Exposures found in software components. Because modern software is complex with its many layers, interdependencies, data input, and libraries, vulnerabilities tend to emerge over time. Ignoring a high CVE score…

The post Why Understanding CVEs Is Critical for Data Scientists appeared first on Anaconda.



from Planet SciPy
read more

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...