Featured

30 best tricks in python to make your code look more professional

Python is quite a popular language among others for its simplicity and readability of the code. It is one of the simplest languages to choose as your first language. If you are a beginner with the basic concepts of python then this is the best time to learn to write better codes.

There are a lot of tricks in python that can improve your program better than before. This article will help you to know various tricks and tips available in python. Practice them continuously until it becomes a part of your programming habit.

Trick 01 – Multiple Assignment for Variables

Python allows us to assign values for more than one variable in a single line. The variables can be separated using commas. The one-liners for multiple assignments has lots of benefits. It can be used for assigning multiple values for multiple variables or multiple values for a single variable name. Let us take a problem statement in which we have to assign the values 50 and 60 to the variables a and b. The usual code will be like the following.

a = 50 
b = 60
print(a,b)
print(type(a))
print(type(b))

Output

50 60
<class 'int'>
<class 'int'>

Condition I – Values equal to Variables

When the variables and values of multiple assignments are equal, each value will be stored in all the variables.

a , b = 50 , 60
print(a,b)
print(type(a))
print(type(b))

Output

50 60
<class 'int'>
<class 'int'>

Both the programs gives the same results. This is the benefit of using one line value assignments.

Condition II – Values greater than Variables

Let us try to increase the number of values in the previous program. The multiple values can be assigned to a single variable. While assigning more than one value to a variable we must use an asterisk before the variable name.

a , *b = 50 , 60 , 70
print(a)
print(b)
print(type(a))
print(type(b))

Output

50
[60, 70]
<class 'int'>
<class 'list'>

The first value will be assigned to the first variable. The second variable will take a collection of values from the given values. This will create a list type object.

Condition III – One Value to Multiple Variables

We can assign a value to more than one variable. Each variable will be separated using an equal to symbol.

a = b = c = 50
print(a,b,c)
print(type(a))
print(type(b))
print(type(c))

Output

50 50 50
<class 'int'>
<class 'int'>
<class 'int'>

Trick 02 – Swapping Two Variables

Swapping is the process of exchanging the values of two variables with each other. This can be useful in many operations in computer science. Here, I have written two major methods used by the programmer to swap the values as well as the optimal solution.

Method I – Using a temporary variable

This method uses a temporary variable to store some data. The following code is written with temporary variable name.

a , b = 50 , 60
print(a,b)
temp = a+b #a=50 b=60 temp=110
b = a #a=50 b=50 temp=110
a = temp-b #a=60 b=50 temp=110
print("After swapping:",a,b)

Output

50 60
After swapping: 60 50

Method II – Without using a temporary variable

The following code swaps the variable without using a temporary variable.

a , b = 50 , 60
print(a,b)
a = a+b #a=110 b=60
b = a-b #a=110 b=50
a = a-b #a=60 b=50
print("After swapping:",a,b)

Output

50 60
After swapping: 60 50

Method III – Optimal Solution in Python

This is a different approach to swap variables using python. In the previous section, we have learned about multiple assignments. We can use the concept of swapping.

a , b = 50 , 60
print(a,b)a , b = b , a
print("After swapping",a,b)

Output

50 60
After swapping 60 50

Trick 03 – Reversing a String

There is an another cool trick for reversing a string in python. The concept used for reversing a string is called string slicing. Any string can be reversed using the symbol [::-1] after the variable name.

my_string = "MY STRING"
rev_string = my_string[::-1]
print(rev_string)

http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68Output

GNIRTS YM

Trick 04 – Splitting Words in a Line

No special algorithm is required for splitting the words in a line. We can use the keyword split() for this purpose. Here I have written two methods for splitting the words.http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68http://click.e.hostingmessages.com/?qs=1b7e5bf595e2a1718714f4d0451786b858b04ef76a65e862d9553b57d6f54fefd5bb44c3c2a5a83f737215f7ffb08b6112a0dd5f3e278a68

Method I – Using iterations

my_string = "This is a string in Python"
start = 0
end = 0
my_list = []for x in my_string:
end=end+1
if(x==' '):
my_list.append(my_string[start:end])
start=end+1
my_list.append(my_string[start:end+1])
print(my_list)

Output

['This ', 'is ', 'a ', 'string ', 'in ', 'Python']

Method II – Using split function

my_string = "This is a string in Python"
my_list = my_string.split(' ')
print(my_list)

Output

['This ', 'is ', 'a ', 'string ', 'in ', 'Python']

Trick 05 – List of words into a line

This is the opposite process of the previous one. In this part we are going to convert a list of words into a single line using join function. The syntax for using join function is given below.

Syntax: “ ”.join(string)

my_list = ['This' , 'is' , 'a' , 'string' , 'in' , 'Python']
my_string = " ".join(my_list)

Output

This is a string in Python

Trick 06 – Printing a string multiple times

We can use the multiplication operator to print a string for multiple times. This is a very effective way to repeat a string.

n = int(input("How many times you need to repeat:"))
my_string = "Python\n"
print(my_string*n)

Output

How many times you need to repeat:3
Python
Python
Python

Trick 07 – Joining Two strings using addition operator

Joining various strings can be done without using the join function. We can just use the addition operator (+) to do this.

a = "I Love "
b = "Python"
print(a+b)

Output

I Love Python

Trick 08 – More than one Conditional Operators

Two combine two or more conditional operators in a program we can use the logical operators. But the same result can be obtained by chaining the operators. For example, if we need to do print something when a variable has the value greater than 10 and less than 20, the code will be something like the following.

a = 15
if (a>10 and a<20):
print("Hi")

Instead of this we can combine the conditional operator into single expression.

a = 15
if (10 < a < 20):
print("Hi")

Output

Hi

Learn more about operators in the following article.An Essential Guide on Python for BeginnersA Guide To Learn Python From The NatureMedium.com

Trick 09 – Find most frequent element in a list

The element which occurs most of the time in a list then it will be the most frequent element in the list. The following snippet will help you to get the most frequent element from a list.

my_list = [1,2,3,1,1,4,2,1]
most_frequent = max(set(my_list),key=my_list.count)
print(most_frequent)

Output

1

Trick 10 – Find Occurrence of all elements in list

The previous code will give the most frequent value. If we need to know the occurrence of all the unique element in a list, then we can go for the collection module. The collections is a wonderful module in python which gives great features. The Counter method gives a dictionary with the element and occurrence pair. thank

from collections import Counter
my_list = [1,2,3,1,4,1,5,5]
print(Counter(my_list))

Output

Counter({1: 3, 5: 2, 2: 1, 3: 1, 4: 1})

Trick 11 – Checking for Anagram of Two strings

Two strings are anagrams if one string is made up of the characters in the other string. We can use the same Counter method from the collections module.

from collections import Counter
my_string_1 = "RACECAR"
my_string_2 = "CARRACE"if(Counter(my_string_1) == Counter(my_string_2)):
print("Anagram")
else:
print("Not Anagram")

Output

Anagram

Trick 12 – Create Number Sequence with range

The function range() is useful for creating a sequence of numbers. It can be useful in many code snippets. The syntax for a range function is written here.

Syntax: range(start, end, step)

Let us try to create a list of even numbers.

my_list = list(range(2,20,2))
print(my_list)

Output

[2, 4, 6, 8, 10, 12, 14, 16, 18]

Trick 13 – Repeating the element multiple times

Similar to the string multiplication we can create a list filled with an element multiple times using multiplication operator.

my_list = [3]
my_list = my_list*5
print(my_list)

Output

[3, 3, 3, 3, 3]

Trick 14 – Using Conditions in Ternary Operator

In most of the time, we use nested conditional structures in Python. Instead of using nested structure, a single line can be replaced with the help of ternary operator. The syntax is given below.

Syntax: Statement1 if True else Statement2

age = 25
print(“Eligible”) if age>20 else print(“Not Eligible”)

Output

Eligible

Trick 15 – List Comprehension with Python

List comprehension is a very compact way to create a list from another list. Look at the following codes. The first one is written using simple iteration and the second one is created using list comprehension.

square_list = []
for x in range(1,10):
temp = x**2
square_list.append(temp)
print(square_list)

Output

[1, 4, 9, 16, 25, 36, 49, 64, 81]

Using List Comprehension

square_list = [x**2 for x in range(1,10)]
print(square_list)

Output

[1, 4, 9, 16, 25, 36, 49, 64, 81]

Trick 16 – Convert Mutable into Immutable

The function frozenset() is used to convert mutable iterable into immutable object. Using this we can freeze an object from changing its value.

my_list = [1,2,3,4,5]
my_list = frozenset(my_list)
my_list[3]=7
print(my_list)

Output

Traceback (most recent call last):
File "<string>", line 3, in <module>
TypeError: 'frozenset' object does not support item assignment

As we applied the frozenset() function on the list, the item assignment is restricted.

Trick 17 – Rounding off with Floor and Ceil

Floor and Ceil are mathematical functions can be used on floating numbers. The floor function returns an integer smaller than the floating value whereas the ceil function returns the integer greater than the floating value. To use this functions we have to import math module.

import math
my_number = 18.7
print(math.floor(my_number))
print(math.ceil(my_number))

Output

18
19

Trick 18 – Returning Boolean Values

Some times we have to return a boolean value by checking conditions of certain parameters. Instead of writing if else statements we can directly return the condition. The following programs will produce the same output.

Method I – Using If Else Condition

def function(n):
if(n>10):
return True
else:
return False
n = int(input())
if(function(n)):
print("Eligible")
else:
print("Not Eligible")

Method II – Without If Else Condition

def function(n):
return n>10n = int(input())
print("Eligible") if function(n) else print("Not Eligible")

Output

11
Eligible

Trick 19 – Create functions in one line

Lambda is an anonymous function in python that creates function in one line. The syntax for using a lambda function is given here.

Syntax: lambda arguments: expression

x = lambda a,b,c : a+b+c
print(x(10,20,30))

Output

60

Trick 20 – Apply function for all elements in list

Map is a higher order function that applies a particular function for all the elements in list.

Syntax: map(function, iterable)

my_list = ["felix", "antony"]
new_list = map(str.capitalize,my_list)
print(list(new_list))

Output

['Felix', 'Antony']

Trick 21 – Using Lambda with Map function

The function can be replaced by a lambda function in python. The following program is created for creating square of list of numbers.

my_list = [1, 2, 3, 4, 5]
new_list = map(lambda x: x*x, my_list)
print(list(new_list))

Output

[1, 4, 9, 16, 25]

Learn more about higher order functions here.Advanced Function Concepts in PythonTime To Learn Advanced Functions Such As Map, Filter And MoreMedium.com

Trick 22 – Return multiple values from a function

A python function can return more than one value without any extra need. We can just return the values by separating them by commas.

def function(n):
return 1,2,3,4
a,b,c,d = function(5)
print(a,b,c,d)

Output

1 2 3 4

Trick 23 – Filtering the values using filter function

Filter function is used for filtering some values from a iterable object. The syntax for filter function is given below.

Syntax: filter(function, iterable)

def eligibility(age):
return age>=24
list_of_age = [10, 24, 27, 33, 30, 18, 17, 21, 26, 25]
age = filter(eligibility, list_of_age)print(list(age))

Output

[24, 27, 33, 30, 26, 25]

Trick 24 – Merging Two Dictionaries in Python

In python, we can merge two dictionaries without any specific method. Below code is an example for merging two dictionaries.

dict_1 = {'One':1, 'Two':2}
dict_2 = {'Two':2, 'Three':3}
dictionary = {**dict_1, **dict_2}
print(dictionary)

Output

{'One': 1, 'Two': 2, 'Three': 3}

Trick 25 – Getting size of an object

The memory size varies based on the type of object. We can get the memory of an object using getsizeof() function from the sys module.

import sys
a = 5
print(sys.getsizeof(a))

Output

28

Trick 26 – Combining two lists into dictionary

The zip unction has many advantages in python. Using zip function we can create a dictionary from two lists.

list_1 = ["One","Two","Three"]
list_2 = [1,2,3]
dictionary = dict(zip(list_1, list_2))
print(dictionary)

Output

{'Two': 2, 'One': 1, 'Three': 3}

Trick 27 – Calculating execution time for a program

Time is another useful module in python can be used to calculate the execution time.

import time
start = time.clock()
for x in range(1000):
pass
end = time.clock()
total = end - start
print(total)

Output

0.00011900000000000105

Trick 28 – Removing Duplicate elements in list

An element that occurs more than one time is called duplicate element. We can remove the duplicate elements simply using typecasting.

my_list = [1,4,1,8,2,8,4,5]
my_list = list(set(my_list))
print(my_list)

Output

[8, 1, 2, 4, 5]

Trick 29 – Printing monthly calendar in python

Calendar module has many function related to the date based operations. We can print monthly calendar using the following code.

import calendar
print(calendar.month("2020","06"))

Output

     June 2020
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

Trick 30 – Iterating with zip function

The zip functions enables the process of iterating more than one iterable using loops. In the below code two lists are getting iterated simultaneously.

list_1 = ['a','b','c']
list_2 = [1,2,3]
for x,y in zip(list_1, list_2):
print(x,y)

Output

a 1
b 2
c 3

Closing Thoughts

I hope you enjoyed this article. As an end note, you have to understand that learning the tricks is not a must. But if you do so, you can stand unique among other programmers. Continuous practice is must to become fluent in coding. Thank you for reading this article.

<a href="https://www.bluehost.com/track/nevilpurpp/" target="_blank"> <img border="0" src="https://bluehost-cdn.com/media/partner/images/nevilpurpp/120x90/120x90BW.png"> </a>
https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js

The proportion of tor anonymity users in free countries

Significance

Measuring the proportion of Tor anonymity network users who employ the system for malicious purposes is important as this technology can facilitate child abuse, the sale of illicit drugs, and the distribution of malware. We show that only a small fraction of users globally (∼6.7%) likely use Tor for malicious purposes on an average day. However, this proportion clusters unevenly across countries, with more potentially malicious Tor users in “free” countries (∼7.8%) than in “not free” regimes (∼4.8%). These results suggest that the countries which host most of the infrastructure of the network and house the Tor Project plausibly experience a disproportional amount of harm from the Tor anonymity network.

Abstract

The Tor anonymity network allows users to protect their privacy and circumvent censorship restrictions but also shields those distributing child abuse content, selling or buying illicit drugs, or sharing malware online. Using data collected from Tor entry nodes, we provide an estimation of the proportion of Tor network users that likely employ the network in putatively good or bad ways. Overall, on an average country/day, ∼6.7% of Tor network users connect to Onion/Hidden Services that are disproportionately used for illicit purposes. We also show that the likely balance of beneficial and malicious use of Tor is unevenly spread globally and systematically varies based upon a country’s political conditions. In particular, using Freedom House’s coding and terminological classifications, the proportion of often illicit Onion/Hidden Services use is more prevalent (∼7.8%) in “free” countries than in either “partially free” (∼6.7%) or “not free” regimes (∼4.8%).

Debate rages about the social utility of an anonymous portion of the global Internet accessible via the Tor network and colloquially known as the Dark Web (1).* Although other similar tools exist, The Onion Router (Tor) is currently the largest anonymity network. Tor users can act as publishers of content by using the network to anonymously administer Onion/Hidden Services for the use of others. They can also use the Tor browser to anonymously read either these Onion/Hidden Services (i.e., sites with rendezvous points located internal to the Tor network) or to access Clear Web sites (15). With these diverse supply-side and demand-side functions (6), many point to the socially harmful uses of Tor as an anonymous platform for child abuse imagery sites (78), illicit drug markets (913), gun sales (1415), and potential extremist content that has shifted to the Dark Web after extensive Clear Web content moderation efforts (16). Others emphasize its socially beneficial potential as a privacy-enhancing tool and censorship circumvention technology (1722).

Both sides of the debate illustrate genuine uses of the technology. Like any tool that is inherently dual use, questions abound about whether its benefits are worth the costs. Such questions have both net (i.e., do costs or benefits predominate) and distributional (i.e., how are the harms/benefits spread out) dimensions. Overall, a technology like the Tor anonymity network might do more harm than good. It may also be more harmful in some locations than others. Ultimately, these are empirical questions.

In the case of the Tor anonymity network, our data provide clear, if probabilistic, answers to these questions. Our data show that in net terms, only a small fraction of Tor users employ the anonymity system for likely malicious purposes. On an average day during our sample period, for example, about 6.7% of Tor network clients globally use the network to connect to “Onion/Hidden Services” that are predominantly used for illicit and illegal activities, such as buying drugs, distributing malware, or consuming and sharing child abuse imagery content. To be sure, there some socially beneficial content on Onion/Hidden Services and plenty of troubling content on the Clear Web. However, substantial evidence has shown that the preponderance of Onion/Hidden Services traffic connects to illicit sites (7). With this important caveat in mind, our data also show that the distribution of potentially harmful and beneficial uses is uneven, clustering predominantly in politically free regimes. In particular, the average rate of likely malicious use of Tor in our data for countries coded by Freedom House as “not free” is just 4.8%. In countries coded as “free,” the percentage of users visiting Onion/Hidden Services as a proportion of total daily Tor use is nearly twice as much or ∼7.8%. These findings are robust to a different measure of political freedom and the inclusion of a variety of statistical controls. They also give rise to a number of important public policy challenges.

Data, Material, and Methods

Our data were collected by running 1 percent of entry (Guard) nodes in the Tor network from December 31, 2018, to August 18, 2019, with a short interruption to data collection from May 4, 2019, to May 13, 2019. Tor clients (users) randomly choose an entry node from the set of available nodes in the network (weighted by available bandwidth). By running 1 percent of Guard nodes, we observe a random sample of all Tor relay users, although our data do not include those who employ Tor bridges to access the network. By analyzing unique signatures in the traffic (e.g., directory lookups), we can distinguish whether clients are using Tor to visit either the Clear Web (e.g., CNN.com) or a Tor Onion/Hidden Service (e.g., xyz.onion). This process does not reveal anything about the precise content a user is querying. Additionally, we geolocate the user’s incoming IP address to a country of origin and aggregate these data into 1) a count of all Tor network users per country per day and 2) a count of Onion/Hidden Services users per country per day.

We merge these aggregate Tor network data with measures of country-level political freedom, taken from both Freedom House’s annual Freedom in the World reports (2324) and the “PolityV Political Regime Characteristics and Transitions” dataset (25); the most recent available country-level indicators for wealth, Internet penetration, and population size from the World Bank (26); and an estimate of per capita Darknet cryptomarket activity at a country level in the years immediately preceding our study period (27). Table 1 provides a descriptive summary of the data.

Table 1.

Descriptive statistics

Initial ethics approval for the data collection infrastructure was granted by the University of Portsmouth Ethics Committee (ETHICS-GO1). An additional “not human subjects research” determination was made by Virginia Tech’s Institutional Review Board (20-576), as all data for this project were analyzed in aggregate at a country level and user IP addresses were not included in any dataset used for the analysis. IP addresses were translated at source using Maxmind’s Geolocation Service.

To approximate the potential harms and benefits of Tor, we measure the percentage of a country’s total Tor clients that go to Tor Onion/Hidden Services on the average day in the observed time range (hereafter %HS).

Interpreting this variable as a country-level measure of the potential illicit use of Tor requires an assumption about the nature of Tor traffic. For our purposes, we assume that a larger share of Tor Clear Web users likely employ the Tor anonymity network for rights-based uses (i.e., privacy protection or censorship circumvention) than Onion/Hidden Services users. Conversely, we assume that a larger share of Tor clients heading to Onion/Hidden Services are more likely to be engaged in predominately illicit activities, such as visiting child abuse sites, drug markets, or hacker forums than is common among Tor Clear Web users.

While this assumed pattern is not universally true (e.g., Facebook and the New York Times have commonly used Onion/Hidden Services and many Clear Web sites host extremist content or other illicit material), there are four reasons why this assumption might be generally, that is to say probabilistically, correct.

First, for users who employ Tor to access Clear Web content, the destination sites have known/knowable administrators and web services providers. These features of Clear Web content allow for greater transparency and content moderation and can minimize (although not eliminate) the possibility that users are engaging with content that is widely considered malicious or illegal (162829).

In contrast, while the majority of hosted Onion/Hidden Services are often not per se illegal (2830), user demand for this content tends to suggest that illicit use of Onion/Hidden Services predominates (6). First, one 2015 study investigating site visits to Onion/Hidden Services found that roughly 82% of requests over a 6-month observation period went to child abuse imagery sites, although this period also corresponded with a major FBI investigation into the Playpen child abuse imagery site (7). Second, a number of empirical investigations have documented the rapid growth of drug cryptomarkets, even while the average global number of Tor users remains relatively constant over time (2931). Since Snowden’s disclosures of National Security Agency surveillance in 2013, for example, Tor network use has stabilized to around 2 to 2.5 million users per day (232). During this same period, cryptomarket vendor counts alone have increased from reportedly 3,877 unique vendor accounts on Silk Road at the time of its closure in October 2013 to ∼40,000 vendors on AlphaBay in 2017, just four short years later (3334). Third, cryptomarkets originally had a significant political dimension to them, often coupling the sale of drugs with discussion of libertarianism and politics (13536). The Silk Road site administrator, Ross Ulbritch (also known as the Dread Pirate Roberts), even hosted a political book club via the site. These political dimensions, however, have declined significantly over time, leaving largely just drug exchange (37).

In combination, past findings such as these suggest that users of Onion/Hidden Services content tends to cluster heavily toward malicious/illicit/illegal uses, although many benign or even beneficial Onion/Hidden Services sites do exist (12836). In contrast, use of Tor to access Clear Web content implies that users are browsing sites where the operators of the accessed content are known/knowable, and so comparatively less likely to be hosting content that is widely agreed to be illegal or malicious, although illicit or illegal activity certainly still does occur on the Clear Web (1628). In sum, the current study relies upon a well-documented if probabilistic pattern: A larger share of Onion/Hidden Services users are likely to be engaged in illicit activity than Tor Clear Web users.

Net Dimensions.

Our data suggest that over time and across all countries, users of the Tor anonymity network predominately employ the system to venture to Clear Web content. Aggregating daily observations into a country’s daily average and then tabulating these values suggests that, overall, just 6.7% of Tor users during the study period in 2019 visited Onion/Hidden Services sites. Framed differently, only about 1 in 20 Tor users on an average day may be employing the system for potentially illicit purposes. The remainder of the users employed the Tor network to view Clear Web sites, suggesting that approximately upwards of 93% of Tor users globally go to websites on the Clear Web that are not administered anonymously and so comparatively less likely to be hosting malicious or illegal content. In net terms, these data suggest that the bulk of Tor users are, on an average daily basis, doing comparatively licit things with the Tor anonymity network and are not viewing Onion/Hidden Services content.

Extrapolating our average %HS estimate onto the total daily number of Tor network clients at a global level reveals the scale of the potentially benign and malicious use of Tor. The Tor Project publishes aggregate daily client counts per country, collected by observing requests for Tor Directory sites and mirrors (2). Like our own data, these numbers do not reveal the number of unique Tor users, only the number of distinct connection requests. For the full observation period of our data excluding the 9-d period of interrupted data collection, the average daily number of Tor relay clients is 2,231,334 connections globally. Using a strict version of our simplifying assumption and combining our estimates of the overall %HS with this total count indicates that on an average day in 2019 about 149,499 Tor network clients (nonunique) were potentially using the network to engage in possibly illicit activity on Onion/Hidden Services. Inversely, of course, this also implies that on an average day in 2019 upwards of 2,081,834 Tor users visited likely benign Clear Web content.

Distributional Dimensions.

Our data suggest that likely malicious/benign users of the Tor anonymity network are not evenly spread globally and, in fact, vary systematically based upon prevalent political conditions within a country. These results are in line with the predictions of the need/opportunity framework, which posits that the opportunity to use Tor should be the predominant driver of use in free regimes and that the political need to use anonymity-enhancing technologies should be the primary driver of use in not free regimes (1921). The analysis in this section is broken into three parts: 1) cross-sectional and longitudinal summary findings by aggregate political conditions; 2) cross-sectional trends by disaggregated political conditions; and 3) tests of the robustness of the main findings once controlling for confounders such as wealth, population size, estimated country-level cryptomarket activity, and Internet penetration rates, as well as an alternative measure of political freedom.

Aggregate Political Freedom Levels and the Malicious Use of Tor.

A country’s political conditions systematically predict the degree to which users within that jurisdiction employ the Tor anonymity network for potentially licit or illicit purposes. Fig. 1, for example, presents the %HS variable for countries coded as “free” (n = 86), “partially free” (n = 59), or “not free” (n = 50) by Freedom House for which we have Tor usage data. The violin plot shows that the density of average daily %HS in “not free” regimes is significantly lower than the same proportion of Tor users in “free” countries. More precisely, a significantly greater share of Tor users in free countries go to Onion/Hidden Services (free %HS = 7.8%) than the global average of %HS = 6.7%. Nearly all of the countries with %HS of greater than 15% are categorized as “free.” Users in “partially free” regimes have average daily %HS users (partially free %HS = 6.7%), comparable to the global average. Onion/Hidden Services have significantly fewer users of Tor in “not free” regimes such as China, Russia, or Algeria as a proportion of local connections (not free %HS = 4.8%).

Fig. 1.

Fig. 1.

More politically “free” countries have higher proportions of Hidden Services traffic than is present in either “partially free” or “not free” nations (n = 195 countries). Each point indicates the average daily %HS for a given country. The white regions represent the kernel density distributions for each ordinal category of political freedom (“free,” “partially free,” and “not free”).

Fig. 2 plots the average %HS variable by political conditions over the full observation period. The ordinal ranking of “free,” “partially free,” and “not free” remains relatively constant throughout this period, suggesting that the core findings are not driven by outlying, short-run blocks of time. Interestingly, the results also suggest that from early-to-late 2019 there was a fairly steady increase in the proportion of users visiting Onion/Hidden Service in all regime types. There was a large spike in the %HS variable in late August 2019. The reasons for the increase are unclear but do not detract from this study’s claims regarding the global distribution of Onion/Hidden Services use since the ordinal ranking of the %HS by political conditions remains the same as predicted even during this period of anomalous volume.

Fig. 2.

Fig. 2.

Throughout the observed time period (12/31/2018–8/18/2019), “free” countries typically had a higher proportion of Hidden Services traffic than either “partially free” or “not free” nations on a daily basis. The green, cyan, and mauve lines indicate the average daily %HS for “free,” “partially free,” and “not free” countries, respectively (n = 37,922 country-days).

Disaggregated Political Freedom Measures and the Potential Illicit Use of Tor.

Political freedoms/restrictions take many forms, some of which might be more relevant to the potential illicit use of Tor than others. Freedom House’s “free,” “partially free,” and “not free” categories are aggregates of a country’s level of political freedom and civil liberties. Each of these two categories, in turn, breaks down into additional, more refined subcategories. Political Rights (range 0–12) is composed of: 1) the freedom of a country’s electoral processes, 2) its levels of political pluralism, and 3) the functioning of its government. Civil Liberties (range 0–16) is composed of: 1) freedom of expression and belief, 2) associational and organizational rights, 3) rule of law and 4) personal autonomy and individual rights (2324). In each case, higher scores correspond with higher levels of freedom and rights protection.

Fig. 3 shows the association between a country’s various subcategory political conditions and its %HS. Each subcategory of political freedom exhibits a positive correlation with a higher %HS. Correlation coefficients suggest that the “function of government” and “individual rights” variables are a bit more strongly associated with higher %HS, but generally the pattern exhibited by every subcategory of political rights and civil liberties is the same. Increases in political freedom correlate with higher %HS or, essentially, a greater share of potentially illicit users of Tor.

Fig. 3.

Fig. 3.

Data show a positive association between Freedom House’s political freedom subcategories and average daily %HS. Each graph represents a different aspect of political freedom (the freedom of a country’s “electoral process,” its levels of “political pluralism and participation,” the “functioning of government,” the extent of “freedom of expression and belief,” “associational and organizational rights,” “rule of law,” and “personal autonomy/individual rights”). The same 195 countries (each represented by a point) appear in all seven graph. The blue line in each graph is a linear fitted line for the association between each subcategory of political freedom and %HS.

What of Potential Confounders or Other Measures of Political Conditions?

A number of other factors might also correlate with Tor anonymity network usage and act as potential confounders. Tor might, for example, be a tool of the wealthy, be functionally useful only in larger populations due to how it produces anonymity, require a certain amount of aggregate Internet penetration, or cluster in countries that are high users of cryptomarkets (1938). These potential confounders suggest that the correlation between country-level political conditions and %HS might be spurious. Additionally, while Freedom House provides a widely used assessment of political conditions around the world, no measure is without its potential blind spots. The results presented above might, therefore, be driven by some unknown feature of Freedom House’s coding schema and may not be robust to alternative measures of country-level political conditions.

The regression models presented in Table 2 test the robustness of the core finding to both the inclusion of a number of controls (i.e., country wealth, population size, Internet penetration rates, and estimated cryptomarket activity) and alternative dependent variable specifications. Across all models, increasing political freedom, regardless of the political freedom measure used, correlates positively with a higher %HS. In the full models (models 3 and 6), only country political conditions and Internet penetration rates correlate significantly with the %HS variable. Neither wealth, population size, nor a cryptomarket sales volume activity measure correlate significantly with %HS.

Table 2.

Ordinary Least Squares regression on two measures of country-level political conditions

The effect size of the political freedom variables is also substantively large. Moving from the lowest to highest observed levels of political freedom in the two full models (models 3 and 6), for example, increases the predicted %HS by 2.39 percentage points using the Freedom House scoring and by 3.42 percentage points using the Polity2 measure. In short, the association between country-level political conditions and %HS is highly consistent, surviving both the inclusion of other country-level variables and alternative measures of political freedom.

Discussion

Our results make two primary contributions to knowledge and have a number of implications.

First, while other studies have measured and parsed malicious Tor network traffic (39), our study provides a viable estimates of how users, as distinct from the traffic they generate, employ the Tor anonymity network. On this front, our results show that most users on an average day are using Tor to view and engage with Clear Web content, not Onion/Hidden Services. Based upon a strict reading of our simplifying assumption, this finding suggests that most users of Tor are likely engaged in predominately licit or even rights-based activities. Debates about the future of encryption and anonymity-granting technologies should weigh carefully such preponderance of potential use.

Second, as predicted elsewhere (1921), the findings contribute to our understanding of the global spread of the potential harms/benefits of Tor. Our results suggest that likely licit and illicit use of the Tor anonymity network is highly uneven and varies systematically by political context. Potentially harmful uses of Tor tend to cluster predominately in “free” regimes and users who are more likely leveraging the network for rights-based purposes tend to cluster in “not free” countries. These trends befit the dual-use nature of the Tor anonymity network. The distribution of this pattern is relatively stable over time and common across all subcategories of political rights and civil liberties. It is, finally, political context that is more strongly associated with %HS levels, not other potential confounders like wealth, cryptomarket usage, or population size—although Internet penetration rates also matter.

These results have a number of consequences for research and policy. First, the results suggest that anonymity-granting technologies such as Tor present a clear public policy challenge and include clear political context and geographical components. This policy challenge is referred to in the literature as the “Dark Web dilemma” (21). At the root of the dilemma is the so-called “harm principle” proposed in On Liberty by John Stuart Mill (40). In this principle, it is morally permissible to undertake any action so long as it does not cause someone else harm. The challenge of the Tor anonymity network, as intimated by its dual use nature, is that maximal policy solutions all promise to cause harm to some party. Leaving the Tor network up and free from law enforcement investigation is likely to lead to direct and indirect harms that results from the system being used by those engaged in child exploitation (78), drug exchange (913), and the sale of firearms (1415), although these harms are of course highly heterogeneous in terms of their potential negative social impacts and some, such as personal drug use, might also have predominantly individual costs in some cases. Conversely, simply working to shut down Tor would cause harm to dissidents and human rights activists, particularly, our results suggest, in more repressive, less politically free regimes where technological protections are often needed the most (1920).

Our results showing the uneven distribution of likely licit and illicit users of Tor across countries also suggest that there may be a looming public policy conflagration on the horizon. The Tor network, for example, runs on ∼6,000–6,500 volunteer nodes. While these nodes are distributed across a number of countries, it is plausible that many of these infrastructural points cluster in politically free liberal democratic countries. Additionally, the Tor Project, which manages the code behind the network, is an incorporated not for profit in the United States and traces both its intellectual origins and a large portion of its financial resources to the US government (14142). In other words, much of the physical and protocol infrastructure of the Tor anonymity network is clustered disproportionately in free regimes, especially the United States. Linking this trend with a strict interpretation of our current results suggests that the harms from the Tor anonymity network cluster in free countries hosting the infrastructure of Tor and that the benefits cluster in disproportionately highly repressive regimes.

Like recent debates over encryption developed by predominately Western technology companies (4344), it is plausible that the uneven spread of harms and benefits, when combined with a sense of who can exert jurisdictional control over the infrastructure of the Tor anonymity network, might lead to public policy debates about the future of the technology. Already, survey work suggests that a majority of the global public support shutting down the “Darknet”—a task that is easier said than done, rife with ethical, legal, and technological challenges and sensitive to respondents attitudes toward privacy, censorship, and their previous exposure to online crime (20). The uneven spread of harms/benefits from the Tor anonymity network might feed into this debate and fuel it anew.

Our results suggest two things to this potential debate. First, it is likely that there is some cost redistribution occurring as a result of the dual-use functionalities of Tor anonymity network. In other words, “free” countries are likely bearing an increased social cost of some size (via the harms from hosted child abuse content, illicit drug markets, etc.) so that those in not free regimes might have access to a robust anonymity-enhancing tool. Determining if these increased costs are an acceptable burden to pay so that others might exercise basic political rights is an important normative debate to which the present study supplies some modest empirical results. Second, in the context of any debate about the future of Tor, it is important to bear in mind that our simplifying assumption is merely probabilistic. There are a lot of rights-oriented uses of Onion/Hidden Services so resolving the tensions surrounding Tor by simply closing these sites would not be an unambiguously effective policy approach.

Conclusions

The Tor anonymity network can be used for both licit and illicit purposes. Our results provide a clear, if probabilistic, estimation of the extent to which users of Tor engage in either form of activity. Generally, users of Tor in politically “free” countries are significantly more likely to be using the network in likely illicit ways. A host of additional questions remain, given the anonymous nature of Tor and other similar systems such as I2P and Freenet. Our results narrowly suggest, however, users of Tor in more repressive “not free” regimes tend to be far more likely to venture via the Tor network to Clear Web content and so are comparatively less likely to be engaged in activities that would be widely deemed malicious.

Data Availability.

CSV data for this project, “The potential harms of the Tor anonymity network cluster disproportionately in free countries,” have been deposited in Open Science Foundation and were last accessed on 13 November 2020. The data and code for analysis can be accessed at: https://osf.io/svrdz/?view_only=d676216acb714521b35759238f69c731.

Making apps with python on heroku.

Table of Contents

Introduction

This tutorial will have you deploying a Python app (a simple Django app) in minutes.

Hang on for a few more minutes to learn how it all works, so you can make the most out of Heroku.

The tutorial assumes that you have:

Set up

The Heroku CLI requires Git, the popular version control system. If you don’t already have Git installed, complete the following before proceeding:

In this step you’ll install the Heroku Command Line Interface (CLI). You use the CLI to manage and scale your applications, provision add-ons, view your application logs, and run your application locally.

Download and run the installer for your platform:apple logomacOS

Download the installer

Also available via Homebrew:

$ brew install heroku/brew/heroku

windows logoWindows

Download the appropriate installer for your Windows installation:

64-bit installer

32-bit installerubuntu logoUbuntu 16+

Run the following from your terminal:

$ sudo snap install heroku --classic

Snap is available on other Linux OS’s as well.

Once installed, you can use the herokucommand from your command shell.

Use the heroku login command to log in to the Heroku CLI:

$ heroku login
heroku: Press any key to open up the browser to login or q to exit
 ›   Warning: If browser does not open, visit
 ›   https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com

This command opens your web browser to the Heroku login page. If your browser is already logged in to Heroku, simply click the Log inbutton displayed on the page.

This authentication is required for both the heroku and git commands to work correctly.

If you’re behind a firewall that requires use of a proxy to connect with external HTTP/HTTPS services, you can set the HTTP_PROXY or HTTPS_PROXY environment variablesin your local development environment before running the heroku command.

Prepare the app

In this step, you will prepare a simple application that can be deployed.

To clone the sample application so that you have a local version of the code that you can then deploy to Heroku, execute the following commands in your local command shell or terminal:

$ git clone https://github.com/heroku/python-getting-started.git
$ cd python-getting-started

You now have a functioning git repository that contains a simple application, a runtime.txtspecifying Python 3.7.6, and a requirements.txt, which is used by Python’s dependency manager, Pip.

Deploy the app

In this step you will deploy the app to Heroku.

Create an app on Heroku, which prepares Heroku to receive your source code:

$ heroku create
Creating app... done, ⬢ serene-caverns-82714
https://serene-caverns-82714.herokuapp.com/ | https://git.heroku.com/serene-caverns-82714.git

When you create an app, a git remote (called heroku) is also created and associated with your local git repository.

Heroku generates a random name (in this case serene-caverns-82714) for your app, or you can pass a parameter to specify your own app name.

Now deploy your code:

$ git push heroku main
Counting objects: 407, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (182/182), done.
Writing objects: 100% (407/407), 68.65 KiB | 68.65 MiB/s, done.
Total 407 (delta 199), reused 407 (delta 199)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.7.6
remote: -----> Installing pip
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote:        Collecting django (from -r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 1))
remote:          Downloading https://files.pythonhosted.org/packages/32/ab/22530cc1b2114e6067eece94a333d6c749fa1c56a009f0721e51c181ea53/Django-2.1.2-py3-none-any.whl (7.3MB)
remote:        Collecting gunicorn (from -r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 2))
remote:          Downloading https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl (112kB)
remote:        Collecting django-heroku (from -r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 3))
remote:          Downloading https://files.pythonhosted.org/packages/59/af/5475a876c5addd5a3494db47d9f7be93cc14d3a7603542b194572791b6c6/django_heroku-0.3.1-py2.py3-none-any.whl
remote:        Collecting pytz (from django->-r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 1))
remote:          Downloading https://files.pythonhosted.org/packages/30/4e/27c34b62430286c6d59177a0842ed90dc789ce5d1ed740887653b898779a/pytz-2018.5-py2.py3-none-any.whl (510kB)
remote:        Collecting psycopg2 (from django-heroku->-r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 3))
remote:          Downloading https://files.pythonhosted.org/packages/37/88/40748331bf75d068a07bbea7dc658faceb0ce2e9fffdde550e76d5475e59/psycopg2-2.7.5-cp37-cp37m-manylinux1_x86_64.whl (2.7MB)
remote:        Collecting dj-database-url>=0.5.0 (from django-heroku->-r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 3))
remote:          Downloading https://files.pythonhosted.org/packages/d4/a6/4b8578c1848690d0c307c7c0596af2077536c9ef2a04d42b00fabaa7e49d/dj_database_url-0.5.0-py2.py3-none-any.whl
remote:        Collecting whitenoise (from django-heroku->-r /tmp/build_394859b69f6aeb1b63e599ce5b6c69bd/requirements.txt (line 3))
remote:          Downloading https://files.pythonhosted.org/packages/07/2e/c77e71cb448f1a507bc2dfec1d5c24e35d14a737837bea6cdfd6d1ff66bd/whitenoise-4.1-py2.py3-none-any.whl
remote:        Installing collected packages: pytz, django, gunicorn, psycopg2, dj-database-url, whitenoise, django-heroku
remote:        Successfully installed dj-database-url-0.5.0 django-2.1.2 django-heroku-0.3.1 gunicorn-19.9.0 psycopg2-2.7.5 pytz-2018.5 whitenoise-4.1
remote: -----> $ python manage.py collectstatic --noinput
remote:        131 static files copied to '/tmp/build_a72377875f1c522b087e93a543bac7d5/staticfiles', 411 post-processed.
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 57.1M
remote: -----> Launching...
remote:        Released v5
remote:        https://serene-caverns-82714.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/serene-caverns-82714.git
 * [new branch]      revert-to-requirements -> main

The application is now deployed. Ensure that at least one instance of the app is running:

$ heroku ps:scale web=1

Now visit the app at the URL generated by its app name. As a handy shortcut, you can open the website as follows:

$ heroku open

View logs

Heroku treats logs as streams of time-ordered events aggregated from the output streams of all your app and Heroku components, providing a single channel for all of the events.

View information about your running app using one of the logging commandsheroku logs --tail:

$ heroku logs --tail
2018-10-12T19:13:57.748721+00:00 heroku[web.1]: Starting process with command `gunicorn gettingstarted.wsgi`
2018-10-12T19:13:59.308299+00:00 app[web.1]: [2018-10-12 19:13:59 +0000] [4] [INFO] Starting gunicorn 19.9.0
2018-10-12T19:13:59.308880+00:00 app[web.1]: [2018-10-12 19:13:59 +0000] [4] [INFO] Using worker: sync
2018-10-12T19:13:59.308777+00:00 app[web.1]: [2018-10-12 19:13:59 +0000] [4] [INFO] Listening at: http://0.0.0.0:3142 (4)
2018-10-12T19:13:59.313176+00:00 app[web.1]: [2018-10-12 19:13:59 +0000] [10] [INFO] Booting worker with pid: 10
2018-10-12T19:13:59.331441+00:00 app[web.1]: [2018-10-12 19:13:59 +0000] [11] [INFO] Booting worker with pid: 11
2018-10-12T19:13:59.864677+00:00 heroku[web.1]: State changed from starting to up
2018-10-12T19:14:03.000000+00:00 app[api]: Build succeeded
2018-10-12T19:19:00.370216+00:00 heroku[router]: at=info method=GET path="/" host=serene-caverns-82714.herokuapp.com request_id=308ae087-635f-4cf8-8ae4-7184dfb23012 fwd="204.14.239.106" dyno=web.1 connect=1ms service=21ms status=200 bytes=7616 protocol=https

Visit your application in the browser again, and you’ll see another log message generated.

Press Control+C to stop streaming the logs.

Define a Procfile

Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start your app.

The Procfile in the example app you deployed looks like this:

web: gunicorn gettingstarted.wsgi --log-file -

This declares a single process type, web, and the command needed to run it. The name webis important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed.

Procfiles can contain additional process types. For example, you might declare one for a background worker process that processes items off of a queue.

Microsoft Windows

The sample app has an additional Procfile for local development on Microsoft Windows, located in the file Procfile.windows. Later tutorial steps will use this instead: it starts a different web server, one that is compatible with Windows.

web: python manage.py runserver 0.0.0.0:5000

Scale the app

Right now, your app is running on a single web dyno. Think of a dyno as a lightweight container that runs the command specified in the Procfile.

You can check how many dynos are running using the ps command:

$ heroku ps
Free dyno hours quota remaining this month: 999h 6m (99%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): gunicorn gettingstarted.wsgi (1)
web.1: up 2018/10/12 14:26:45 -0500 (~ 33s ago)

By default, your app is deployed on a free dyno. Free dynos will sleep after a half hour of inactivity (if they don’t receive any traffic). This causes a delay of a few seconds for the first request upon waking. Subsequent requests will perform normally. Free dynos also consume from a monthly, account-level quota of free dyno hours – as long as the quota is not exhausted, all free apps can continue to run.

To avoid dyno sleeping, you can upgrade to a hobby or professional dyno type as described in the Dyno Types article. For example, if you migrate your app to a professional dyno, you can easily scale it by running a command telling Heroku to execute a specific number of dynos, each running your web process type.

Scaling an application on Heroku is equivalent to changing the number of dynos that are running. Scale the number of web dynos to zero:

$ heroku ps:scale web=0

Access the app again by hitting refresh on the web tab, or heroku open to open it in a web tab. You will get an error message because you no longer have any web dynos available to serve requests.

Scale it up again:

$ heroku ps:scale web=1

For abuse prevention, scaling a non-free application to more than one dyno requires account verification.

Declare app dependencies

Heroku recognizes an app as a Python app by looking for key files. Including a requirements.txt in the root directory is one way for Heroku to recognize your Python app.

The demo app you deployed already has a requirements.txt, and it looks something like this:

django
gunicorn
django-heroku

The requirements.txt file lists the app dependencies together. When an app is deployed, Heroku reads this file and installs the appropriate Python dependencies using the pip install -r command.

To do this locally, you can run the following command:

$ pip install -r requirements.txt

Note: Postgres must be properly installed in order for this step to work properly.

Note: if you’re running Linux, the libpq-devsystem package (or equivalent for your distribution) must also be installed.

Installing the dependencies also caused several other dependencies to be installed. You can see them by using pip’s feature list:

$ pip list
Package         Version
--------------- -------
dj-database-url 0.5.0
Django          2.1.2
django-heroku   0.3.1
gunicorn        19.9.0
pip             10.0.1
psycopg2        2.7.5
pytz            2018.5
setuptools      39.0.1
whitenoise      4.1

Once dependencies are installed, you will be ready to run your app locally.

Run the app locally

The app is almost ready to start locally. Django uses local assets, so first, you’ll need to run collectstatic:

$ python manage.py collectstatic

Respond with “yes”.

Now start your application locally using heroku local, which was installed as part of the Heroku CLI.

If you’re on Microsoft Windows system, run this:

$ heroku local web -f Procfile.windows

If you’re on a Unix system, just use the default Procfile by running:

$ heroku local web

Your local web server will then start up:

[OKAY] Loaded ENV .env File as KEY=VALUE Format
2:28:11 PM web.1 |  [2018-10-12 14:28:11 -0500] [18712] [INFO] Starting gunicorn 19.9.0
2:28:11 PM web.1 |  [2018-10-12 14:28:11 -0500] [18712] [INFO] Listening at: http://0.0.0.0:5000 (18712)
2:28:11 PM web.1 |  [2018-10-12 14:28:11 -0500] [18712] [INFO] Using worker: sync
2:28:11 PM web.1 |  [2018-10-12 14:28:11 -0500] [18715] [INFO] Booting worker with pid: 18715

Just like Heroku, heroku local examines the Procfile to determine what to run.

Open http://localhost:5000 with your web browser. You should see your app running locally.

To stop the app from running locally, go back to your terminal window and press Ctrl+C to exit.

Push local changes

In this step you’ll learn how to propagate a local change to the application through to Heroku. As an example, you’ll modify the application to add an additional dependency and the code to use it.

Install requests locally:

$ pip install requests

And then add it to your requirements.txt file:

django
gunicorn
django-heroku
requests

Modify hello/views.py so that it imports the requests module at the start:

import requests

Now modify the index method to make use of the module. Try replacing the current indexmethod with the following code:

def index(request):
    r = requests.get('http://httpbin.org/status/418')
    print(r.text)
    return HttpResponse('<pre>' + r.text + '</pre>')

Now test locally:

$ heroku local

Visit your application at http://localhost:5000. You should now see the output of fetching http://httpbin.org/status/418, which is a lovely teapot:

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`

Now deploy. Almost every deploy to Heroku follows this same pattern. First, add the modified files to the local git repository:

$ git add .

Now commit the changes to the repository:

$ git commit -m "Demo"

Now deploy, just as you did previously:

$ git push heroku main

Finally, check that everything is working:

$ heroku open

Provision add-ons

Add-ons are third-party cloud services that provide out-of-the-box additional services for your application, from persistence through logging to monitoring and more.

By default, Heroku stores 1500 lines of logs from your application. However, it makes the full log stream available as a service – and several add-on providers have written logging services that provide things such as log persistence, search, and email and SMS alerts.

In this step you will provision one of these logging add-ons, Papertrail.

Provision the papertrail logging add-on:

$ heroku addons:create papertrail
Adding papertrail on sharp-rain-871... done, v4 (free)
Welcome to Papertrail. Questions and ideas are welcome (support@papertrailapp.com). Happy logging!
Use `heroku addons:docs papertrail` to view documentation.

To help with abuse prevention, provisioning an add-on requires account verification. If your account has not been verified, you will be directed to visit the verification site.

The add-on is now deployed and configured for your application. You can list add-ons for your app like so:

$ heroku addons

To see this particular add-on in action, visit your application’s Heroku URL a few times. Each visit will generate more log messages, which should now get routed to the papertrail add-on. Visit the papertrail console to see the log messages:

$ heroku addons:open papertrail

Your browser will open up a Papertrail web console, showing the latest log events. The interface lets you search and set up alerts:

Screenshot of the console

Start a console

You can run a command, typically scripts and applications that are part of your app, in a one-off dyno using the heroku run command. It can also be used to launch a REPL process attached to your local terminal for experimenting in your app’s environment:

$ heroku run python manage.py shell
Python 3.7.6 (default, Dec 23 2019, 04:25:22)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

If you receive an error, Error connecting to process, then you may need to configure your firewall.

The Python shell is running in the context of your app and all its dependencies. From here you can import some of your application files. For example, you will be be able to run the following:

>>> import requests
>>> print(requests.get('http://httpbin.org/status/418').text)

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`
>>> exit()

To get a real feel for how dynos work, you can create another one-off dyno and run the bashcommand, which opens up a shell on that dyno. You can then execute commands there. Each dyno has its own ephemeral filespace, populated with your app and its dependencies – once the command completes (in this case, bash), the dyno is removed.

$ heroku run bash
Running `bash` attached to terminal... up, run.3052
~ $ ls
gettingstarted  hello  manage.py  Procfile  README.md  requirements.txt  runtime.txt  staticfiles
~ $ exit
exit

Don’t forget to type exit to exit the shell and terminate the dyno.

Define config vars

Heroku lets you externalise configuration – storing data such as encryption keys or external resource addresses in config vars.

At runtime, config vars are exposed as environment variables to the application.

Edit hello/views.py. At the beginning, add a line to import the os module:

import os

Now modify the index method so that it repeats an action depending on the value of the TIMES environment variable:

def index(request):
    times = int(os.environ.get('TIMES',3))
    return HttpResponse('Hello! ' * times)

heroku local will automatically set up the environment based on the contents of the .env file in your local directory. In the top-level directory of your project there is already a .env file that has the following contents:

TIMES=2

If you run the app with heroku local, you’ll see two “Hello!”‘s.

To set the config var on Heroku, execute the following:

$ heroku config:set TIMES=2

View the config vars that are set using heroku config:

$ heroku config
== sharp-rain-871 Config Vars
PAPERTRAIL_API_TOKEN: erdKhPeeeehIcdfY7ne
TIMES: 2

Deploy your changed application to Heroku to see this in action.

Provision a database

The add-on marketplace has a large number of data stores, from Redis and MongoDB providers, to Postgres and MySQL. In this step you will learn about the free Heroku Postgres add-on that was automatically provisioned when your app was deployed.

A database is an add-on, and so you can find out a little more about the database provisioned for your app using the addonscommand in the CLI:

$ heroku addons
Add-on                                         Plan       Price  State
─────────────────────────────────────────────  ─────────  ─────  ───────
heroku-postgresql (postgresql-horizontal-27446)  hobby-dev  free   created
 └─ as DATABASE
...

Listing the config vars for your app will display the URL that your app is using to connect to the database, DATABASE_URL:

$ heroku config
=== serene-caverns-82714 Config Vars
DATABASE_URL: postgres://qayojflkqzwdlk:c9b49b89f95625e0c1ed225aed3871a888ab41ca53d6d16078fe5f6416f8a402@ec2-23-23-80-20.compute-1.amazonaws.com:5432/dbr6s55rtq1vqg

Heroku also provides a pg command that shows a lot more:

$ heroku pg
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            10.5
Created:               2018-10-12 19:13 UTC
Data Size:             7.6 MB
Tables:                0
Rows:                  0/10000 (In compliance) - refreshing
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-horizontal-27446

This indicates I have a hobby database (free), running Postgres 10.5, with no data.

The example app you deployed already has database functionality, which you should be able to reach by visiting your app’s URL and appending /db. For example, if your app was deployed to https://wonderful-app-287.herokuapp.com/ then visit https://wonderful-app-287.herokuapp.com/db.

Accessing it will yield an error though, because while the database is configured, the tables have not been created. Run the standard Django manage.py migrate to create the tables.

$ heroku run python manage.py migrate
Running `python manage.py migrate` attached to terminal... up, run.1059
Synchronizing apps without migrations:
  Creating tables...
    Creating table hello_greeting
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
...

If you see a message that says, “You just installed Django’s auth system, which means you don’t have any superusers defined. Would you like to create one now?”, type no.

Now access the /db route again and you’ll see a simple page update every time you access it:

Page View Report

April 19, 2017, 8:50 a.m.
April 19, 2017, 8:52 a.m.

The code to access the database is straightforward, and makes use of a simple Django model called Greetings that you can find in hello/models.py.

Whenever you visit the /db route of your app, the following method in the hello/views.pyfile is invoked which creates a new Greeting and then renders all the existing Greetings:

def db(request):

    greeting = Greeting()
    greeting.save()

    greetings = Greeting.objects.all()

    return render(request, 'db.html', {'greetings': greetings})

Assuming that you have Postgres installed locally, use the heroku pg:psql command to connect to the remote database and see all the rows:

$ heroku pg:psql
--> Connecting to postgresql-horizontal-27446
psql (10.5)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

serene-caverns-82714::DATABASE=>

Read more about Heroku PostgreSQL.

A similar technique can be used to install MongoDB or Redis add-ons.

Next steps

You now know how to deploy an app, change its configuration, view logs, scale, and attach add-ons.

Here’s some recommended reading. The first, an article, will give you a firmer understanding of the basics. The second is a pointer to the main Python category here on Dev Center.

Please subscribe to my blog I will be eriwrit about more programming languages you can use on heroku.

3 best iPhone 12 to buy this season

Hey.. still have that old iPhone, is it boring and hard to get the latest features. Feeling outdated walking with it. Maybe you want to get a relative or a friend a gift for this festive season , and still not sure what to buy.

Well we all experience the same problems, but lucky for you I did some research and I found three iPhone 12 that will be perfect for you and your family..

iPhone 12 pro max
iPhone 12 pro
iPhone 12 max

I hope you enjoy , thanks for reading my article remember to ,.. subscribe and comment … you also share us on social media

Best way to unlock your phone if you forget the pattern.

1.Connect your Android phone to you computer.

2. Open commands prompt as administrator.

3. Now in command prompt window type the following codes carefully exactly as it and then press enter. Adb she’ll CD/data/com.android.providers.settings/database sqlit3 setting.db update system set valu which is equals to 0 where name is equals lock pattern auto lock update system set value is equals to 0 where name is equals to lockscreen.lockedoutmanently; quite.

4. Now you will some screen as shown below and then you can rebot your phone and now start your phone again and try unlocking your phone using random lock pattern and it will work pretty fine.

5. If you face any problem repeat same steps but instead of the of the above code try using adb Shell rm/data/ system/ gesture. Key and then press enter and now trying rebooting your device to see if it works.

You can now use this simple trick to unlock your phone if you forget your pattern without losing your data.

Thanks for reading ..please don’t forget to comment and like us on social media

Tech trends

Hey guys this is my first blog. I have just started out, really not sure if I’ll succeed but it’s worth a try. Hope all my viewers will understand.

For a start I’ll be focusing more on tech news and trends . I’ll talk about what’s new , what to buy depending on the season and all that. As time passes by, I will get to learn new things to improve my site .

If you have any questions about the site please comment on the comment section and remember to follow us on social media thank you…