Writing data to the spreadsheet
Anything you can calculate with code, you can write to the spreadsheet — data types such as strings, numbers, and dates work, as well as types like Dataframes because Pandas, NumPy, and SciPy are included by default — giving you the power to manipulate data in a programming language and visualize it on a spreadsheet.
Code -> Spreadsheet
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 64 | |||||||||
1 | ||||||||||
2 | ||||||||||
3 | ||||||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1# Last line writes to the spreadsheet
22 ** 6
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | |||||||||
1 | 2 | |||||||||
2 | 3 | |||||||||
3 | ||||||||||
4 | 4 | 5 | 6 | |||||||
5 | ||||||||||
6 | Col 1 | Col 2 | ||||||||
7 | 7 | 10 | ||||||||
8 | 8 | 11 | ||||||||
9 | 9 | 12 | ||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1# An array fills down (column)
2[1,2,3]
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | source | likes | dislikes | total | ||||||
1 | Mastodon | 81 (20.4%) | 12 (3.0%) | 93 | ||||||
2 | 142 (35.7%) | 41 (10.3%) | 183 | |||||||
3 | Threads | 101 (25.4%) | 21 (5.3%) | 122 | ||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1import pandas as pd
2
3# Imagine some raw data you got somewhere
4data = [
5 { 'source': 'Mastodon', 'likes': 81, 'dislikes': 12 },
6 { 'source': 'Twitter', 'likes': 142, 'dislikes': 41 },
7 { 'source': 'Threads', 'likes': 101, 'dislikes': 21 },
8]
9
10# Turn it into a dataframe
11df = pd.DataFrame(data)
12
13# Add a 'total' column
14df['total'] = df['likes'] + df['dislikes']
15
16# Calculate likes and dislikes as percentages & format
17# e.g. "12" becomes "12 (52%)"
18df['likes'] = df['likes'].apply(
19 lambda x: f'{x} ({x / df["total"].sum() * 100:.1f}%)'
20)
21df['dislikes'] = df['dislikes'].apply(
22 lambda x: f'{x} ({x / df["total"].sum() * 100:.1f}%)'
23)
24
25# Write to the spreadsheet
26df
Reading data from the spreadsheet
Workflows often follow a pattern: take some raw data, transform it, then visualize your work. Quadratic makes this easy by allowing you to programatically read data from anywhere on your spreadsheet, run some calculations on it, then display the results.
Spreadsheet -> code
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 15 | 20 | ||||||||
1 | ||||||||||
2 | 10 | 100 | ||||||||
3 | 20 | 200 | ||||||||
4 | 30 | 300 | ||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1# Read a value from the sheet
2value = cell(0,0)
3
4# Add a number and write it to the sheet
5value + 5
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | ||||||||||
1 | 10 | |||||||||
2 | 20 | 100 | 30 | |||||||
3 | 40 | |||||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1# Read cell values relative to the current cell's position
2one_left = rel_cell(-1, 0)
3one_right = rel_cell(1, 0)
4one_up = rel_cell(0, -1)
5one_down = rel_cell(0, 1)
6
7# Add them and write them to the sheet
8one_left + one_right + one_up + one_down
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | Bytes | Kilobytes | Megabytes | Gigabytes | ||||||
1 | 656786 | 641kB | 0.6MB | 0.0GB | ||||||
2 | 447043536 | 436,566kB | 426.3MB | 0.4GB | ||||||
3 | 761131472 | 743,292kB | 725.9MB | 0.7GB | ||||||
4 | 704723912 | 688,207kB | 672.1MB | 0.7GB | ||||||
5 | 844523850 | 824,730kB | 805.4MB | 0.8GB | ||||||
6 | 643594786 | 628,511kB | 613.8MB | 0.6GB | ||||||
7 | 339763942 | 331,801kB | 324.0MB | 0.3GB | ||||||
8 | 476184258 | 465,024kB | 454.1MB | 0.4GB | ||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1import pandas as pd
2
3# Get the bytes from the spreadsheet
4values = cells((0,1), (0,100))
5
6# Make a dataframe for the output
7df = pd.DataFrame({
8 'Kilobytes': [],
9 'Megabytes': [],
10 'Gigabytes': []
11})
12
13# Iterate over each by and convert to KB, MB, GB
14for index, row in values.iterrows():
15 byte = int(row[0])
16
17 # convert to kilobytes and format
18 kb = round(byte / 1024)
19 kb_str = "{:,}kB".format(kb)
20
21 # convert to megabytes and format
22 mb = round(byte / (1024 * 1024), 1)
23 mb_str = "{:.1f}MB".format(mb)
24
25 # convert to gigabytes and format
26 gb = round(byte / (1024 * 1024 * 1024), 1)
27 gb_str = "{:.1f}GB".format(gb)
28
29 # append to dataframe
30 df.loc[len(df.index)] = [kb_str, mb_str, gb_str]
31
32df
Code or formulas? How about both
In a traditional spreadsheet you use formulas. In Quadratic you can use both formulas and code, whichever best suits the task at hand. Plus, your no-code teammates can still collaborate with you — it’s the best of both worlds.
Formulas + code
A | B | C | D | |||||||
---|---|---|---|---|---|---|---|---|---|---|
0 | 5 | 10 | 10 | |||||||
1 | 5 | |||||||||
2 | ||||||||||
3 | ||||||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1A0 + A1
A | B | C | D | |||||||
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 36 | 36 | |||||||
1 | 2 | |||||||||
2 | 3 | |||||||||
3 | 4 | |||||||||
4 | 5 | |||||||||
5 | 6 | |||||||||
6 | 7 | |||||||||
7 | 8 | |||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1SUM(A0:A7)
A | B | C | D | |||||||
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | Invalid data | ||||||||
1 | 10 | Invalid data | ||||||||
2 | 30 | |||||||||
3 | ||||||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1IF(A0 > 5,
2 IF(A1 > 5,
3 IF(A2 > 5,
4 AVERAGE(A0:A2),
5 'Invalid data'),
6 'Invalid data'),
7 'Invalid data'
8)
Fetch data from any source
Using the primitives of a programming language, you can easily fetch data from an API and work with it in your spreadsheet. Now you can build a live connection to your ever-changing data and your spreadsheet is always up-to-date.
Network
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | NPM downloads yesterday for: react | |||||||||
1 | 3173996 | |||||||||
2 | ||||||||||
3 | ||||||||||
4 | ||||||||||
5 | ||||||||||
6 | ||||||||||
7 | ||||||||||
8 | ||||||||||
9 | ||||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1# Import library for making network requests
2import requests
3
4# Make API call
5response = requests.get(
6 'https://api.npmjs.org/downloads/range/last-day/react'
7)
8
9# Turn to JSON
10json = response.json()
11
12# Write to the spreadsheet
13json['downloads'][0]['downloads']
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | NPM downloads | |||||||||
1 | ||||||||||
2 | Package: | |||||||||
3 | react | |||||||||
4 | ||||||||||
5 | Timeframe: (choose one in code) | |||||||||
6 | last-day | last-week | last-month | |||||||
7 | ||||||||||
8 | Downloads: | |||||||||
9 | 104314059 | |||||||||
10 | ||||||||||
11 | ||||||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1import pandas
2import requests
3
4# Read API parameters from the sheet
5package = cell(0, 3)
6timeframe = cell(2, 6)
7
8# Make API call
9response = requests.get(
10 f'https://api.npmjs.org/downloads/range/{timeframe}/{package}'
11)
12
13# Turn to JSON
14json = response.json()
15
16# Sum total downloads and write to sheet
17sum(item['downloads'] for item in json['downloads'])
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | NPM downloads | |||||||||
1 | ||||||||||
2 | Package: | |||||||||
3 | react-router,next,astro | |||||||||
4 | ||||||||||
5 | Timeframe: (choose one in code) | |||||||||
6 | last-day | last-week | last-month | last-year | ||||||
7 | ||||||||||
8 | Package | From | To | Downloads | ||||||
9 | react-router | 2023-03-28 | 2024-03-27 | 527596865 | ||||||
10 | next | 2023-03-28 | 2024-03-27 | 251260122 | ||||||
11 | astro | 2023-03-28 | 2024-03-27 | 7754640 | ||||||
12 | ||||||||||
13 | ||||||||||
14 | ||||||||||
15 |
1from datetime import datetime, timedelta
2import pandas
3import requests
4
5# Read API parameters from the sheet
6packages_comma_delimited = rel_cell(0, -5)
7timeframe = rel_cell(3, -2)
8
9# Scoped packages, e.g. `@slack/client`, are not yet supported in
10# bulk queries, so we make 1 API call per package
11# https://github.com/npm/registry/blob/master/docs/download-counts.md#per-version-download-counts
12packages = packages_comma_delimited.split(',')
13
14# last-day, last-week, last-month are all keywords in the API
15# but last-year is not, so we'll generate the from/to date range
16# ourselves so it matches the date range format of the API
17# YYYY-MM-DD:YYYY-MM-DD
18if timeframe == 'last-year':
19 today = datetime.today()
20 today_str = today.strftime('%Y-%m-%d')
21 one_year_ago = today - timedelta(days=365)
22 one_year_ago_str = one_year_ago.strftime('%Y-%m-%d')
23 timeframe = f'{one_year_ago_str}:{today_str}'
24
25# Define dataframe with columns
26df = pandas.DataFrame(columns=['Package', 'From', 'To', 'Downloads'])
27
28# Iterate over packages
29for package in packages:
30
31 # Make API call
32 response = requests.get(
33 f'https://api.npmjs.org/downloads/range/{timeframe}/{package}'
34 )
35
36 # Turn to JSON
37 json = response.json()
38
39 # Sum total downloads
40 print(json)
41 total_downloads = sum(
42 item['downloads'] for item in json['downloads']
43 )
44
45 # Append the dataframe
46 df.loc[len(df)] = [package, json['start'], json['end'], total_downloads]
47
48df