Home > Mobile >  How do I convert a string with integers and characters to an integer and it work?
How do I convert a string with integers and characters to an integer and it work?

Time:10-05

from function import *
import requests

def main():
#define your api "endpoint"
  url = "https://swapi.dev/api/people"
  resObj = requests.get(url)
  print("STATUS CODE: ", resObj)

  typewriter("Processed API URL call. Returning JSON object.", 0.01)
  #let's take json and convert to python dictionary
  resDict = resObj.json()
 
  #list of char dictionaries
  characters = resDict['results']
  for character in characters:
    # print(character)
    charBirth = character['birth_year']
    charBirthStrip = charBirth.strip('BBY')
    try:
      charBirthMod = int(float(charBirthStrip))
    except:
      charBirthAD = ''
    charBirthAD = bby(charBirthMod)
    print("Name:", character['name'])
    print("Height:", character['height'], "cm")
    print("Mass:", character['mass'], "kg")
    print("Birth year:", charBirthAD, "AD")
    print("Gender:", character['gender'])
main()

and then the function that is relevant is

def bby(birthyear):
  #0 B.B.Y. (AD 1815)
  adYear = 1815 - birthyear

so my goal here is to convert the returned value from the dictionary in the api such like '49BBY', and take the letters out, convert it to an integer and then do the math equation set in the bby() function. what it is returning is rather this: Birth year: None AD for all characters.

thanks

CodePudding user response:

You need to add returnto your function:

def bby(birthyear):
  #0 B.B.Y. (AD 1815)
  adYear = 1815 - birthyear
  return adYear

EDIT:

In the exception you may try something like this, because in your code when you'll have an exception It will always try to use bby

    try:
        charBirthAD = bby(int(float(charBirthStrip)))
    except Exception as e:
        charBirthAD = ''

CodePudding user response:

after you get the string : '49BBY'

you get the integer with this:

import re
your_str = '49BBY'
temp = re.findall(r'\d ', your_str)
result = int(temp[0])

and if you want the function return value, you need to add this to your function:

return your_value_to_return

CodePudding user response:

This is much better dealt with using control structures (dictionaries).

The specific issue around birth_year can be dealt with easily. The API returns birth_year either as 'unknown' or nBBY (where n is 1 or more digits). Therefore you just need to check to see what the string ends with.

Consider this:

from requests import Session
from requests.exceptions import HTTPError

url = 'https://swapi.dev/api/people/'

def bby(s):
    if s.endswith('BBY'):
        return int(1815 - float(s[:-3]))
    return s

# keys that require suffixes
suffix = {'height': 'cm', 'mass': 'kg'}
# keys and their output mappings
keys = {'name': 'Name', 'height': 'Height', 'mass': 'Mass', 'birth_year': 'Birth year', 'gender': 'Gender'}
# keys that require conversion
convert = {'birth_year': bby}
# parameters
params = {'page': 1}

with Session() as session:
    while True:
        try:
            (r := session.get(url, params=params)).raise_for_status()
            j = r.json()
            for d in j['results']:
                for k, v in keys.items():
                    value = d.get(k, 'unknown')
                    if (func := convert.get(k)):
                        value = func(value)
                    if value != 'unknown' and (sfx := suffix.get(k)):
                        print(f'{v}: {value}{sfx}')
                    else:
                        print(f'{v}: {value}')
            params['page']  = 1
        except HTTPError:
            break

The processing is fixed. What's variable is what's in the control dictionaries. You can add or take away functionality without modifying the main code just by making appropriate adjustments to those structures.

Partial output:

Name: Luke Skywalker
Height: 172cm
Mass: 77kg
Birth year: 1796
Gender: male
Name: C-3PO
Height: 167cm
Mass: 75kg
Birth year: 1703
Gender: n/a
Name: R2-D2
Height: 96cm
Mass: 32kg
Birth year: 1782
Gender: n/a
Name: Darth Vader
Height: 202cm
Mass: 136kg
Birth year: 1773
Gender: male
Name: Leia Organa
Height: 150cm
Mass: 49kg
Birth year: 1796
Gender: female
Name: Owen Lars
Height: 178cm
Mass: 120kg
Birth year: 1763
Gender: male
Name: Beru Whitesun lars
Height: 165cm
Mass: 75kg
Birth year: 1768
Gender: female
Name: R5-D4
Height: 97cm
Mass: 32kg
Birth year: unknown
Gender: n/a
Name: Biggs Darklighter
Height: 183cm
Mass: 84kg
Birth year: 1791
Gender: male
Name: Obi-Wan Kenobi
Height: 182cm
Mass: 77kg
Birth year: 1758
Gender: male
Name: Anakin Skywalker
Height: 188cm
Mass: 84kg
Birth year: 1773
Gender: male
Name: Wilhuff Tarkin
Height: 180cm
Mass: unknown
Birth year: 1751
Gender: male
Name: Chewbacca
Height: 228cm
Mass: 112kg
Birth year: 1615
Gender: male
Name: Han Solo
Height: 180cm
Mass: 80kg
Birth year: 1786
Gender: male
Name: Greedo
Height: 173cm
Mass: 74kg
Birth year: 1771
Gender: male
Name: Jabba Desilijic Tiure
Height: 175cm
Mass: 1,358kg
Birth year: 1215
Gender: hermaphrodite
Name: Wedge Antilles
Height: 170cm
Mass: 77kg
Birth year: 1794
Gender: male

CodePudding user response:

If you want to avoid additional imports and make function/method as explicit as possible and strictly doing what you described, you can write:

def bby(date_bby: str, date: int) -> int:
    """
    :param date_bby: e.g. '49BBY'
    :param date: e.g. 1815
    """
    try:
        return int(''.join(filter(str.isdigit, date_bby))) - date
    except ValueError:
        print("BBY date was somehow invalid.")
        return date

Update I've added a try-except statement in accordance to @OldBill comment.

  • Related